Skip to content

Instantly share code, notes, and snippets.

@rjsen
Last active December 9, 2015 00:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rjsen/57d42de5cb32d3c12670 to your computer and use it in GitHub Desktop.
Save rjsen/57d42de5cb32d3c12670 to your computer and use it in GitHub Desktop.
Scala FP exercise
/*
This is a port of Tony Morris' Haskell beginner list exercises from (http://blog.tmorris.net/posts/haskell-beginner-exercises-with-tests/index.html).
To run, compile with `scalac Main.scala` and then run `scala Main`.
*/
import scala.{List => _, :: => _, Nil => _}
sealed trait List[+T] {
def head: T
def tail: List[T]
def isEmpty: Boolean
def ::[U >: T](el: U): List[U] = new ::(el, this)
def foldLeft[U](init: U)(fun: (U, T) => U): U = this match {
case Nil => init
case x :: xs => xs.foldLeft(fun(init, x))(fun)
}
def foldRight[U](init: U)(fun: (T, U) => U): U = this match {
case Nil => init
case x :: xs => fun(x, xs.foldRight(init)(fun))
}
def equals[U](that: List[U]): Boolean = {
(this.head == that.head) && (this.tail == that.tail)
}
/*
These are the functions to implement using the primitives defined above
*/
def sum[U >: T](implicit num: Numeric[U]): U = ???
def length: Int = ???
def map[U](fun: T => U): List[U] = ???
def filter(fun: T => Boolean): List[T] = ???
def append[U >: T](that: List[U]): List[U] = ???
def flatten[U](implicit ev: T => List[U]): List[U] = ???
def flatMap[U](fun: T => List[U]): List[U] = ???
def max[U >: T](implicit ord: Ordering[U]): Option[T] = ???
def reverse: List[T] = ???
}
case class ::[T](hd: T, tl: List[T]) extends List[T] {
override def head = hd
override def tail = tl
override def isEmpty = false
}
case object Nil extends List[Nothing] {
override def head = throw new NoSuchElementException("head on empty list")
override def tail = throw new UnsupportedOperationException("tail on empty list")
override def isEmpty = true
}
object List {
def apply[T](elems: T*): List[T] = {
if (elems.isEmpty) Nil else elems.head :: apply(elems.tail:_*)
}
}
object Main extends App {
println("running tests...")
val listNum = List(1,2,3,4)
assert(listNum.sum == 10, "sum")
assert(List[Int]().sum == 0, "sum")
assert(listNum.length == 4, "length")
assert(Nil.length == 0, "length")
assert(listNum.map(_ + 1) == List(2,3,4,5), "map")
assert(Nil.map(_.toString) == Nil, "map")
assert(listNum.filter(_ % 2 == 0) == List(2,4), "filter")
assert(Nil.filter(_ == 2) == Nil)
assert(listNum.append(List(5,6)) == List(1,2,3,4,5,6), "append")
assert(Nil.append(List(1,2)) == List(1,2), "append")
assert(List(List(1,2), List(3,4)).flatten == listNum, "flatten")
assert(Nil.flatten == Nil, "flatten")
assert(listNum.flatMap(x => List(x)) == listNum, "flatMap")
assert(Nil.flatMap(x => List(x)) == Nil, "flatMap")
assert(listNum.max.contains(4), "max")
assert(List[Int]().max.isEmpty, "max")
assert(listNum.reverse == List(4,3,2,1), "reverse")
assert(Nil.reverse == Nil, "reverse")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment