1

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 标记。这适用于重载的递归 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 时代一样表达自己:-)

4

1 回答 1

4

A:关于不可变、相互依赖的类的初始化,请看这个问题

B:关于您的问题render: Foo => String功能与Renderable超类,恕我直言,这或多或少是功能和面向对象方法之间的设计决定。我个人不认为其中一个优于另一个,这只是品味问题。论文“Independently Extensible Solutions to the Expression Problem”对两者进行了很好的比较,尽管在稍微复杂的上下文中(然而,这是一本很好的读物)。

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

D:在您当前的类层次结构中,并没有重要的公共超类型IssueField这使得很难为 提供有意义的返回类型fromXML。不过,您可以使用Either[Issue, Field],但这对我来说看起来很可疑。一般来说,我会避免将应该返回成熟节点(例如Task)的函数与返回“内部”节点(例如Status)的函数混合。

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

于 2012-08-06T20:20:50.447 回答