I was trying to solve Exercise 2 from Functional Programming in Scala. The question is as follows:
EXERCISE 2: Write a function take for returning the first n elements of a Stream. def take(n: Int): Stream[A]
My solution is as follows:
import Stream._
trait Stream[+A]{
def uncons:Option[(A,Stream[A])]
def isEmpty:Boolean = uncons.isEmpty
def toList:List[A] = {
val listBuffer = new collection.mutable.ListBuffer[A]
@annotation.tailrec
def go(str:Stream[A]):List[A] = str uncons match {
case Some((a,tail)) => listBuffer += a;go(tail)
case _ => listBuffer.toList
}
go(this)
}
def take(n:Int):Stream[A] = uncons match {
case Some((hd,tl)) if (n > 0) => cons(hd,tl.take(n-1))
case _ => Stream()
}
}
object Stream{
def empty[A]:Stream[A] = new Stream[A]{def uncons = None}
def cons[A](hd: => A,tl: => Stream[A]):Stream[A] = new Stream[A]{
lazy val uncons = Some((hd,tl))
}
def apply[A](as: A*):Stream[A] = {
if(as.isEmpty) empty else
cons(as.head,apply(as.tail: _ *))
}
}
I store this as Stream2.scala and then from the REPL I execute the following:
:load Stream2.scala
When the REPL tries to load my script, it barfs with the following errors:
scala> :load Stream2.scala
Loading Stream2.scala...
import Stream._
<console>:24: error: type mismatch;
found : Stream[A]
required: scala.collection.immutable.Stream[?]
case Some((hd,tl)) if (n > 0) => cons(hd,tl.take(n-1))
^
<console>:25: error: type mismatch;
found : scala.collection.immutable.Stream[Nothing]
required: Stream[A]
case _ => Stream()
^
<console>:11: error: object creation impossible, since method tailDefined in class Stream of type => Boolean is not defined
def empty[A]:Stream[A] = new Stream[A]{def uncons = None}
^
<console>:12: error: object creation impossible, since method tailDefined in class Stream of type => Boolean is not defined
def cons[A](hd: => A,tl: => Stream[A]):Stream[A] = new Stream[A]{
Can somebody point out what might be going wrong here?
scalac Stream2.scala
. It can be that the REPL doesn't connect the companion object to theStream
trait. Also there seems to be some interference from the standard libraryStream
(which shares the same name as yourStream
). Compiling outside the REPL may provide longer error messages. – huynhjl