Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
fp:lab06 [2022/03/25 09:30]
pdmatei
fp:lab06 [2022/04/08 12:45] (current)
pdmatei
Line 1: Line 1:
-====== Lab 06. Datatypes ​in Scala ======+====== Lab 06. Polymorphism ​in Scala ======
  
-Consider ​the following implementation of a simple datatypes to encode natural number:+This lab will start with the implementations discussed during lecture. Please find the polymorphic trait ''​FList[A]''​ below:
 <code scala> <code scala>
-trait Nat {} +trait FList[A]// list with elements of type A 
-case object Zero extends Nat {} +  def length: Int 
-case class Succ(nNatextends Nat {} +  def head: A 
- +  def tail: FList[A] 
-val three Succ(Succ(Succ(Zero)))+  def map[B](fA => 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 || _) 
 +   
 +}
 </​code>​ </​code>​
  
-Write a function which converts a ''​Nat''​ into an ''​Int''​:+together with the implementations:
 <code scala> <code scala>
-def toInt(nNat): Int +case class FNil[A]() extends FList[A]{ 
-  ​n match +  override ​def length: Int = 0 
-    ​case Zero => ??? +  override def head: A = throw new Exception("head on empty list"​) 
-    ​case Succ(n) => ???+  override def tailFList[A] = throw new Exception("​head on empty list") 
 +  override def map[B](f=> 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)
   }   }
 +
 </​code>​ </​code>​
 +
 +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 in the case classes?
 +
 +**6.1.** ''​indexOf''​ determines the position of a value in the list (starting with 0)
 +<code scala>
 +def indexOf(e: A): Int
 +</​code>​
 +
 +**6.2.** ''​update''​ creates a new list where the given position is modified with a new value:
 +<code scala>
 +//​Cons(1,​Cons(2,​Cons(3,​FNil()))).update(9,​1) = Cons(1,​Cons(9,​Cons(3,​FNil())))
 +def update(e: A, pos: Int): FList[A]
 +</​code>​
 +
 +**6.3.** ''​append''​ concatenates this list to another:
 +<code scala>
 +def append(l: FList[A]): FList[A]
 +</​code>​
 +
 +**6.4.** ''​reverse''​ returns the reversed list:
 +<code scala>
 +def reverse: FList[A]
 +</​code>​
 +
 +**6.5.** ''​last''​ returns the last element of the list:
 +<code scala>
 +def last: A
 +</​code>​
 +
 +**6.6.** ''​filter''​ filters the elements of the list:
 +<code scala>
 +def filter(p: A => Boolean): FList[A]
 +</​code>​
 +
 +**6.7.** ''​zip''​ combines two lists into a list of pairs. If **either** list is larger, the remaining elements are discarded.
 +<code scala>
 +// Cons(1,​(Cons(2,​Cons(3,​FNil()))).zip(Cons(true,​Cons(false,​Cons(true,​FNil())))) =
 +// Cons((1,​true),​Cons((2,​false),​Cons((3,​true),​FNil())))
 +def zip[B](l: FList[B]): FList[(A,​B)]
 +</​code>​
 +
 +**6.8.** ''​insSorted''​ inserts an element into a sorted list so that the result is a sorted list.
 +<code scala>
 +def insSorted(f:​ A => Int)(e: A): FList[A]
 +</​code>​
 +
 +**6.9.** ''​sortBy''​ sorts a list using insertion sort.
 +<code scala>
 +def sortBy(f: A => Int): FList[A]
 +</​code>​
 +
 +**6.10 (!)** Implement a method ''​pack''​ which encodes a sorted list as follows:
 +<code scala>
 +[1,​1,​1,​2,​3,​4,​4,​5,​6].pack = [(1,​3),​(2,​1),​(3,​1),​(4,​2),​(5,​1),​(6,​1)]
 +def pack: FList[(A,​Int)]
 +</​code>​
 +