最近Scalaの勉強を始めたので、FizzBuzzを作ってみました。
Fizz Buzz - Wikipedia
無限リストを利用し、条件式を追加することなくFizzとBuzz以外にも約数と出力文字列のペアを無数に追加することが可能になっています。
再帰関数を使用していますが、無名関数は自身を直接呼び出す事が出来ないので、Yコンビネータで代用しています。
不動点コンビネータ - Wikipedia
object Main extends App {
def fizzBuzz(n: Int) {
// 約数と文字列のリスト
val ms = List[(Int, String)](
(3, "Fizz"),
(5, "Buzz")
)
// Yコンビネータ
def Y[A, B](f: ((A => B), A) => B, x: A): B = f((y: A) => Y(f, y), x)
// タプルを無限リスト化
val _ms = ms.map((t: (Int, String)) =>
Y((f: Int => Stream[String], x: Int) => (if (x % t._1 == 0) t._2 else "") #:: f(x + 1), 1)
)
// 無限リストから取り出しと連結を必要数行う
0 until n map (x => _ms.foldLeft("")((a, b) => a + b(x)) match {
case "" => (x + 1).toString()
case x => x
}) foreach (println)
}
fizzBuzz(20)
}
うーん、関数型言語は難しい。
コメント