如何在scala中定义此类
data NestedList a = Elem a | List [NestedList a]
这在Haskell中意味着NestedList是一个Type,它可以包含Elem或另一个NestedList。是否可以在scala中执行这些递归定义?
实际上这就是我想要实现的目标
点击此页面中的Problem 7。
更新....
在下面的答案中,我为NestedList
和Elem
创建了NList
特征和案例类。
试图实现flatten
,我被困在这里..
def flatten[T](xs: NestedList[T]): List[T] = xs match{
case Elem(xs) => List(xs)
//case NList //have to fill this case
}
答案 0 :(得分:5)
来自Haskell的代数数据类型在Scala中被惯用地转换为密封的类层次结构。
例如:
sealed abstract class List[+A]
case class Nil extends List[Nothing]
case class Elem[T](head: T, tail: List[T]) extends List[T]
<强>更新强>
托马斯的回答很好地展示了递归类型定义。但是,有趣的是,您无法使NList
成为案例类 - 报告了sameElements
中使用的合成方法equals
的类型错误。这听起来类似于:https://lampsvn.epfl.ch/trac/scala/ticket/2867
可行的是重复的参数被替换为Seq
:
sealed trait NestedList[A]
case class Elem[A](e : A) extends NestedList[A]
case class NList[A](val e : Seq[NestedList[A]]) extends NestedList[A]
答案 1 :(得分:4)
这应该有用。
sealed trait NestedList[A]
case class Elem[A](val e : A) extends NestedList[A]
case class NList[A](val e : Seq[NestedList[A]]) extends NestedList[A]
def flatten[T](xs: NestedList[T]): Seq[T] = xs match{
case Elem(x) => List(x)
case NList(xs) => xs flatMap (flatten(_))
}
答案 2 :(得分:3)
有关问题的Scala版本,请参阅99 problems in Scala。
该网站的链接解决方案是:
def flatten(ls: List[Any]): List[Any] = ls flatMap {
case ms: List[_] => flatten(ms)
case e => List(e)
}
答案 3 :(得分:1)
sealed abstract class NestedList[A] {
def flatten: NList[A]
}
case class Elem[A](e: A) extends NestedList[A] {
override def flatten = NList(Elem(e))
}
case class NList[A](es: NestedList[A]*) extends NestedList[A] {
override def flatten = NList(es flatMap (_.flatten.es): _*)
}