Commit 745f6582 authored by Alexander Gehrke's avatar Alexander Gehrke
Browse files

Add missing templates for first sheet

parent 4dabef6b
......@@ -9,7 +9,7 @@ usually marked with `???`.
| task sheet | package |
|------------------------------------|-------------------------------------------------------------------|
| 1: Functional Data Structures | \<no templates\> |
| 1: Functional Data Structures | [`fp01`](src/main/scala/fp01) |
| 2: Error Handling | [`fp02`](src/main/scala/fp02) |
| 3: Strictness and Laziness | [`fp03`](src/main/scala/fp03) |
| 4: Laws, Monoids, and Foldable | [`fp04`](src/main/scala/fp04) |
......
package fp01
sealed trait List[+A] {
/**************
* Exercise 1
**************/
def dropWhile(f: A => Boolean): List[A] = ???
/**************
* Exercise 3
**************/
def reverse: List[A] = ???
/**************
* Exercise 4
**************/
def appendViaMatching[AA >: A](other: List[AA]): List[AA] = ???
/**************
* Exercise 5
**************/
def map[B](f: A => B): List[B] = ???
def filter(f: A => Boolean): List[A] = ???
def flatMap[B](f: A => List[B]): List[B] = ???
/**************
* Exercise 6
* for this exercise, you should find the right signatures yourself.
* 6a can be found on the companion object below
**************/
/* 6b) Define zipWith as a generalization of zipAdd
* It should support any datatype inside the lists and any possible operation
* on those types.
* Ideally, even the types of both lists and the resulting list should be
* allowed to be three differnt types
*/
//def zipWith
def head: A = this match {
case Nil => sys.error("head of empty list")
case Cons(h,_) => h
}
def tail: List[A] = this match {
case Nil => sys.error("tail of empty list")
case Cons(_,t) => t
}
def setHead[AA >: A](head: AA): List[AA] = Cons(head, this.tail)
def drop(n: Int): List[A] =
if (n <= 0) this
else this match {
case Nil => Nil
case Cons(_,t) => t.drop(n-1)
}
def init: List[A] = {
@annotation.tailrec
def go(cur: List[A], init: List[A]): List[A] = cur match {
case Nil => sys.error("init of empty list")
case Cons(_,Nil) => init
case Cons(x,xs) => go(xs, Cons(x, init))
}
go(this, Nil).reverse
}
/* implementation from the lecture, not using foldRight */
def appendViaMatching[AA >: A](other: List[AA]): List[AA] =
this match {
case Nil => other
case Cons(x, xs) => Cons(x, xs.append(other))
}
@annotation.tailrec
final def exists[AA >: A](a: AA): Boolean = this match {
case Nil => false
case Cons(x, xs) => if(x == a) true else xs.exists(a)
}
/* For stack safety and performance, the actual implementation for foldRight
* is often foldLeft then reverse */
def foldRight[B](z: B)(f: (A, B) => B): B =
this match {
case Nil => z
case Cons(x, xs) => f(x, xs.foldRight(z)(f))
}
@annotation.tailrec
final def foldLeft[B](z: B)(f: (B, A) => B): B = this match {
case Nil => z
case Cons(x,xs) => xs.foldLeft(f(z,x))(f)
}
}
case object Nil extends List[Nothing]
case class Cons[+A](elem: A, rest: List[A]) extends List[A]
// companion object
object List {
def apply[A](as: A*): List[A] =
if (as.isEmpty) Nil
else Cons(as.head, apply(as.tail: _*))
/**************
* Exercise 6
* for this exercise, you should find the right signatures yourself.
**************/
/* 6a) Define zipAdd to pairwise add elements from two integer lists
* Example: zipAdd(List(1,2,3), List(4,5,6)) should return List(5,7,9)
*/
//def zipAdd
}
package fp01
object Parametricity {
def curry[A,B,C](f: (A,B) => C): A => (B => C) = ???
def uncurry[A,B,C](f: A => (B => C)): (A, B) => C = ???
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment