Reputation: 13
Why do I get an error when trying to implement a linked list in Scala using case classes?
As I am quite familiar with Haskell I am essentially trying to convert this Haskell code into Scala:
Data List = Cons Int List | Nil
instance Show List where
show x = helper x ""
where
helper Nil acc = acc
helper (Cons n xs) acc = let y = acc ++ " " ++ show n in helper xs y
Here is my Scala code:
abstract class List1
case class Cons(head : Int, tail : List1) extends List1
case object Nil extends List1
object thing {
def printList (x : List1) {
var acc = x
while (acc != Nil) {
println (acc.head)
acc = acc.tail
}
}
val a : List1 = Cons(1,Cons(2,Cons(3,Cons(4,Nil))))
printList(a)
}
However, I get a strange error saying that when I call acc.tail, this is not part of List1, nor is Nil, even though they both extend List1. I don't really understand OOP (just procedural and functional programming) so I assume something funky is happening with the type system and the object system.
Upvotes: 1
Views: 108
Reputation: 29538
You could do that very much like in Haskell
def printList(x: List1) = {
x match {
case Cons(hd, tl) => println(hd); printList(tl)
case Nil =>
}
}
Your problem is that acc != Nil
is not enough for the compiler to understand that acc
is a Cons
. head
and tail
are available on Cons
only. Pattern matching is the normal way to go. Otherwise (more object-like), make head
and tail
available in List1
:
sealed trait List1 {
def head: Int
def tail: List1
def isEmpty: Boolean
}
case class Cons(head: Int, tail: List1) extends List1 {
def isEmpty = false
}
case object Nil extends List1 {
def head = sys.error("Head on Nil")
def tail = sys.error("Tail on Nil")
def isEmpty = true
}
Upvotes: 5