関数型プログラミングの魅力:数学式に近い表記で関数定義が可能


「関数型プログラミング言語を使うと、数学式に非常にちかい表記でプログラムが実装できる」ということが実感できた例

フィボナッチ数列

フィボナッチ数列とは、0, 1, 1, 2, 3, 5, 8, 13, 21, ・・・のようにつづいていく数列です。最初の2項以外の項は、直前の2項の和として定義されます。

\begin{array}{l}
a_0=f(0) = 0
\\a_1=f(1) = 1
\\a_2=f(2) = f(1) + f(0) = 1
\\a_3=f(3) = f(2) + f(1) = 2
\\a_4=f(4) = f(3) + f(2) = 3
\\a_5=f(5) = f(4) + f(3) = 5
\\a_6=f(6) = f(5) + f(4) = 8
\\a_n=a_{n-1}+a_{n-2} = f(n-1) + f(n-2) 
\end{array}

0番目からはじまるときのフィボナッチ数列のn番目の要素 $f(n)$ は、数学的には以下のように表現されます。

f(n) = \left\{
 \begin{array}{ll}0 & (n = 0) 
  \\1 & (n = 1) 
  \\f(n-1) + f(n-2) & \{n | n\geq 2, n \in \mathbb{Z}\}
  \end{array}\right.

ここで、$\mathbb{Z}$ は整数集合になります。

F#でフィボナッチ数列を求める関数を実装

上で示した数式に似た表記で関数fibが実装できます。すごい。

code.fs
  let rec fib n:int =
    match n with
    | 0 -> 0
    | 1 -> 1
    | n when n>=2 -> fib(n-1) + fib(n-2) 
    | _ -> raise (Exception("未定義"))

  printfn "f(%d)=%d" 3 (fib 3) // 数列の3番目の要素  
  printfn "f(%d)=%d" 5 (fib 5) // 数列の5番目の要素  

  printfn "%A" <| List.map fib [0 .. 10] 

実行結果

f(3)=2
f(5)=5
[0; 1; 1; 2; 3; 5; 8; 13; 21; 34; 55]