関数型プログラミングとscala

「実践Scala」では1章とって関数型プログラミングについて解説されているので、そこのサンプルコードを則ってscalaの文法を追う。

再帰。

def count(input:String, ch:Char) : Int = {
    var result = 0
  var i = 0
  while(i < input.length) {
    if(input(i) == ch) result += 1
    i += 1
  }
  result
}

末尾再帰(最後に自分自身を再帰呼び出しする)。

def fact(n: Int): BigInt = {
  def f(n: Int, acc: BigInt): BigInt = if (n < 1) acc else f(n - 1, BigInt(n) * acc)
  f(n, 1);
}

リストのメソッド、プレースホルダー構文、遅延評価の線形リストStream。

val nums = List(1, 2, 3, 4, 5)
println(nums.flatMap(x => List(x, x)))
println(nums.flatMap(x => nums.map( y => (x,y)) ))

var list = List("AAAA", "bbbb", "ccc", "DD","e", "Abcde")

println(list.filter(e => e.startsWith("A")))

list.find(e => e.startsWith("A")) match {
  case Some(n) => println(n)
  case one => None
}

nums.span(e => e < 3) match {
  case (x,y) => println(y)
  case _ => None
}

// カリー化の代替としてのプレースホルダー構文
def add(x:Int, y:Int) = x + y
println(List(1, 2, 3).map(add(2, _)))

// 遅延評価される線形リストStream
val lines = Stream.continually(readLine())
for(line <- lines.takeWhile(_ != null)) println(line)

CommonLispをかじってた頃を思い出して少し懐かしくなった…