是否可以在scala中使用相互递归类型?
我有一个包含bugtracker问题列表的xml文件。这是原始数据。该模型具有不同的问题类型,如“任务”,“子任务”,“错误”,“特殊错误”。
现在我想将原始数据解析为任务和子任务的分层结构:
// data type for field contents
abstract class Field
case class Id(raw : string) extends Field
case class Status(raw : string) extends Field
...
// data type for primary model
abstract class Issue(id : String, ...)
case class Task(id : Id, status : Status ..., subtasks : List[Subtask] ) extends Issue(id, ...)
case class Subtask(id : Id, status : Status ..., parent: Task) extends Issue(id, ...)
我想知道这种相互递归在理论上是否可行?
第二个问题:
我将模型渲染到一些wiki-markup。这适用于重载的递归render():类在数据类型中的字符串。 (可能我应该有一个“可渲染的”超类!?)
解析的最简洁方法是什么,即我想要一个递归的
fromXML : scala.xml.Elem => Issue / Field
我会把它放在哪里?它看起来怎么样? IIUC,同伴是自动生成的案例类,所以我不能添加它?
我有这个例子:
def fromXml(e : Elem) = e match {
case <a>test</a> => Id("test")
case _ => Status("Pre-analysed")
}
但是我没有给这个函数一个类型。 该函数的类型是什么?
我还考虑过将xml-elem直接传递给ADT的构造函数,这会很聪明吗?或者我应该将XML解析和模型创建分开?
耶稣,在学习了scala基础知识并完成了一些脚本和函数(以及思考过多的java)之后,我终于明白了如何编写ADT并且可以像在旧的Haskell时代那样表达自己: - )
答案 0 :(得分:4)
答:关于不可变的,相互依赖的类的初始化,请查看this question。
B:关于您的问题render: Foo => String
函数与Renderable
超类,这是恕我直言,或多或少是功能和面向对象方法之间的设计决策。我个人认为其中一个优于另一个,这只是一个品味问题。论文"Independently Extensible Solutions to the Expression Problem"在两者之间有一个很好的比较,虽然在一个稍微复杂的背景下(但这是一个很好的阅读)。
C: Companion对象是由编译器创建的,但是如果你还指定了一个伴随对象,编译器会将两者合并。
D:在您当前的类层次结构中,Issue
和Field
没有非平凡的常用超类型,因此很难为{提供有意义的返回类型{1}}。不过,你可以使用fromXML
,但这看起来很可疑。通常,我会避免混合应该返回完整节点(例如Either[Issue, Field]
)的函数和返回“内部”节点的函数(例如Task
)。