【发布时间】:2020-11-23 08:19:54
【问题描述】:
我正在用 Scala 编写一个 Lisp。
sealed trait Val
final case class Atom(name: String) extends Val
final case object Null extends Val
final class Cons(a: Val, d: => Val) extends Val {
override def toString(): String = "Cons(" + a.toString() + "," + d.toString() + ")"
}
如何正确打印递归Vals?
示例:
lazy val lst:Val = new Cons(Atom("a"), {lst})
lst.toString()
我希望它的结果是#1=Cons(Atom("a"), #1)。
【问题讨论】:
-
这看起来像是一种奇怪的方式来做一个列表。例如,
Cons(Null, Atom("a"))或Cons(Null, Null)是什么意思? -
尚未检查,但请尝试将 Cons 设为案例类。它应该为 toString (以及其他一些东西)生成实现,因此您不必编写它。我相信lazy/ ref 的名字也应该起作用。如果这不是出于学术目的,我建议重新设计您正在做的任何事情。
-
@goozez 您不能将
Cons设为案例类。案例类不能有惰性/按名称参数。 -
如果您正在编写解释器,我会将运行时表示和输入表示分开。然后你可以写
Define(RefName("#1"), Cons(Literal("a"), RefName("#1")))之类的东西,解释器在运行时可以作为递归定义处理,但不会作为内部表示递归。 -
问题应该是“如何实现类似于 ANSI Common Lisp 的 'circle notation'”。
标签: scala functional-programming lisp