続Scala exercises for beginners

Scala exercises for beginnersですが、使ってもいいらしいfoldファミリーで解いてみました。

import org.junit._
import org.junit.Assert._
import org.hamcrest.core.Is._

class EfB {
  def succ(n: Int) = n + 1
  def pred(n: Int) = n - 1
  //---------------------------------------------------------------------------
  @Test def Ex01 {
    assertThat(add(3, 7), is(10))
  }
  def add(x: Int, y: Int): Int = {
    x match {
      case 0 => y
      case _ => add(pred(x), succ(y))
    }
  }
  //---------------------------------------------------------------------------
  @Test def Ex02 {
    assertThat(sum(List(1, 1, 2, 3, 5, 8)), is(20))
  }
  def sum(ls: List[Int]): Int = {
    ls.fold(0) { (a, x) => add(a, x) }
  }
  //---------------------------------------------------------------------------
  @Test def Ex03 {
    assertThat(length(List(1, 1, 2, 3, 5, 8)), is(6))
  }
  def length[T](ls: List[T]): Int = {
    ls.foldLeft(0) { (a, _) => succ(a) }
  }
  //---------------------------------------------------------------------------
  @Test def Ex04 {
    assertThat(map(List(1, 1, 2, 3, 5, 8), { (x: Int) => x.toString }),
      is(List("1", "1", "2", "3", "5", "8")))
  }
  def map[T, U](ls: List[T], f: T => U): List[U] = {
    ls.foldRight(Nil: List[U]) { (x, a) => f(x) :: a }
  }
  //---------------------------------------------------------------------------
  @Test def Ex05 {
    assertThat(filter(List(1, 1, 2, 3, 5, 8), { (x: Int) => x % 2 == 0 }),
      is(List(2, 8)))
  }
  def filter[T](ls: List[T], pred: T => Boolean): List[T] = {
    ls.foldRight(Nil: List[T]) { (x, a) => if (pred(x)) x :: a else a }
  }
  //---------------------------------------------------------------------------
  @Test def Ex06 {
    assertThat(append(List(1, 1, 2), List(3, 5, 8)), is(List(1, 1, 2, 3, 5, 8)))
  }
  def append[T](xs: List[T], ys: List[T]): List[T] = {
    xs.foldRight(ys) { (x, a) => x :: a }
  }
  //---------------------------------------------------------------------------
  @Test def Ex07 {
    assertThat(concat(List(List(1, 1), List(2), List(3, 5, 8))),
      is(List(1, 1, 2, 3, 5, 8)))
  }
  def concat[T](ls: List[List[T]]): List[T] = {
    ls.foldRight(Nil: List[T]) { (x, a) => append(x, a) }
  }
  //---------------------------------------------------------------------------
  @Test def Ex08 {
    assertThat(concatMap(List(1, 1, 2, 3, 5, 8), { (x: Int) => List((x - 1).toString, x.toString) }),
      is(List("0", "1", "0", "1", "1", "2", "2", "3", "4", "5", "7", "8")))
  }
  def concatMap[T, U](ls: List[T], f: T => List[U]): List[U] = {
    ls.foldRight(Nil: List[U]) { (x, a) => append(f(x), a) }
  }
  //---------------------------------------------------------------------------
  @Test def Ex09 {
    assertThat(maximum(List(1, 5, 2, 8, 1, 3)), is(8))
  }
  def maximum(ls: List[Int]): Int = {
    ls.tail.fold(ls.head) { (a, x) => if (a < x) x else a }
  }
  //---------------------------------------------------------------------------
  @Test def Ex10 {
    assertThat(reverse(List(1, 1, 2, 3, 5, 8)), is(List(8, 5, 3, 2, 1, 1)))
  }
  def reverse[T](ls: List[T]): List[T] = {
    ls.foldLeft(Nil: List[T]) { (a, x) => x :: a }
  }
}

こういうリスト関連の問題を解くくらいしかやることが思いつかない。なんかもうひとつチャレンジが必要なんだと思うんですけど、なにかいいお題はないもんですかね。。。