This is an old revision of the document!
Lab 06. Polymorphism in Scala
This lab will start with the implementations discussed during lecture. Please find the polymorphic trait FList[A]
below:
trait FList[A]{ // list with elements of type A def length: Int def head: A def tail: FList[A] def map[B](f: A => B): FList[B] // a op (b op (c op acc)) def foldRight[B](acc: B)(op: (A,B) => B): B // ((acc op a) op b) op c def foldLeft[B](acc: B)(op: (B,A) => B): B def contains(e: A):Boolean = this.foldRight(false)(_ == e || _) }
together with the implementations:
case class FNil[A]() extends FList[A]{ override def length: Int = 0 override def head: A = throw new Exception("head on empty list") override def tail: FList[A] = throw new Exception("head on empty list") override def map[B](f: A => B): FList[B] = FNil[B] override def foldRight[B](acc: B)(op: (A,B) => B): B = acc override def foldLeft[B](acc: B)(op: (B,A) => B): B = acc } case class Cons[A](x:A, xs:FList[A]) extends FList[A]{ override def length = 1 + xs.length override def head:A = x override def tail:FList[A] = xs override def map[B](f: A => B): FList[B] = Cons(f(x),xs.map(f)) override def foldRight[B](acc: B)(op: (A,B) => B): B = op(x, xs.foldRight(acc)(op)) override def foldLeft[B](acc: B)(op: (B,A) => B): B = xs.foldLeft(op(acc,x))(op) } }
Add the following methods in the trait FList
and implement them. Some methods can be directly implemented in the trait, using map
, foldRight
, foldLeft
or other functions. Can you figure which ones are best implemented in the trait and which not?