Определить самоссылочный класс Scala (рекурсивный класс) - PullRequest
4 голосов
/ 16 февраля 2010

Как определить этот класс в scala

data NestedList a = Elem a | List [NestedList a]

Это в Haskell означает, что NestedList - это тип, который может содержать либо Elem, либо другой NestedList. Можно ли делать подобные рекурсивные определения в scala?

На самом деле это то, что я пытаюсь достичь

Проверьте Проблема 7 здесь на этой странице.

Обновлены ....
Следуя приведенным ниже ответам, я создал классы NestedList Trait и case для 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
}

Ответы [ 4 ]

5 голосов
/ 16 февраля 2010

Алгебраические типы данных из 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]

UPDATE

Ответ Томаса прекрасно показывает определение рекурсивного типа. Однако интересно, что вы не можете сделать NList классом case - сообщается об ошибке типа для синтезированного метода 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]
4 голосов
/ 16 февраля 2010

Это должно работать.

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(_)) 
}
3 голосов
/ 16 февраля 2010

См. 99 проблем в Scala для версий проблем Scala.

Связанное решение с этого сайта:

def flatten(ls: List[Any]): List[Any] = ls flatMap {
  case ms: List[_] => flatten(ms)
  case e => List(e)
}
1 голос
/ 16 февраля 2010
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): _*)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...