Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Define self referencing Scala class (recursive class)

How to define this class in scala

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

This in Haskell means a NestedList is a Type which can contain either Elem or another NestedList. Is it possible to do these kind of recursive definitions in scala?

Actually this is what I am trying to acheive

Check Problem 7 here in this page.

Updated....
Follwing the answers below, I created the NestedList Trait and case classes for Elem and NList. Trying to implement the flatten, I am stuck here..

def flatten[T](xs: NestedList[T]): List[T] = xs match{
   case Elem(xs) => List(xs)
   //case NList //have to fill this case
}
like image 620
Teja Kantamneni Avatar asked Dec 14 '22 00:12

Teja Kantamneni


2 Answers

Algebraic Data Types from Haskell are idiomatically translated into sealed class hierarchies in Scala.

For example:

sealed abstract class List[+A]

case class Nil extends List[Nothing]

case class Elem[T](head: T, tail: List[T]) extends List[T]

UPDATE

Thomas's answer shows the recursive type definition nicely. However, it is interesting that you can't make NList a case class -- a type error is reported for the synthesised method sameElements, which is used in equals. This sounds similar to: https://lampsvn.epfl.ch/trac/scala/ticket/2867

It works is the repeated parameters are replaced with 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]
like image 86
retronym Avatar answered Feb 01 '23 02:02

retronym


This should work.

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(_)) 
}
like image 37
Thomas Jung Avatar answered Feb 01 '23 01:02

Thomas Jung