scala中的相互递归类型

时间:2012-08-06 19:49:50

标签: scala functional-programming

是否可以在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时代那样表达自己: - )

1 个答案:

答案 0 :(得分:4)

答:关于不可变的,相互依赖的类的初始化,请查看this question

B:关于您的问题render: Foo => String函数与Renderable超类,这是恕我直言,或多或少是功能和面向对象方法之间的设计决策。我个人认为其中一个优于另一个,这只是一个品味问题。论文"Independently Extensible Solutions to the Expression Problem"在两者之间有一个很好的比较,虽然在一个稍微复杂的背景下(但这是一个很好的阅读)。

C: Companion对象是由编译器创建的,但是如果你还指定了一个伴随对象,编译器会将两者合并。

D:在您当前的类层次结构中,IssueField没有非平凡的常用超类型,因此很难为{提供有意义的返回类型{1}}。不过,你可以使用fromXML,但这看起来很可疑。通常,我会避免混合应该返回完整节点(例如Either[Issue, Field])的函数和返回“内部”节点的函数(例如Task)。

E:您是否看过现有的解决方案,例如scalaxb?您可以找到更多链接herehere