条件分岐

else は省略できない。

# let even n = if n mod 2 = 0 then true else false;;
val even : int -> bool = <fun>
# even 3;;
- : bool = false
# even 8;;
- : bool = true

ところで mod が中置演算子なのはへんな気分だ。

# 9 mod 3;;
- : int = 0
# (mod) 9 2;;
- : int = 1

再帰的な関数

再帰的な関数と定義するには rec をつける。

# let rec fact n = if n = 0 then 1 else n * fact (n - 1);;
val fact : int -> int = <fun>
# fact 3;;
- : int = 6
# fact 6;;
- : int = 720

あまり大きな整数は表現できないらしい。

# fact 30;;
- : int = -738197504

ユークリッドの互除法で最大公約数

プログラミング in OCaml ~関数型プログラミングの基礎からGUI構築まで~ p.51より。再帰的に定義する。

# let rec euclid m n =
if m = n then m
else if m > n then euclid n m
else euclid (n - m) m
;;
val euclid : int -> int -> int = <fun>
# euclid 12 60;;
- : int = 12
# euclid 12 6;;
- : int = 6

基本的には m≦n のつもりで書いているけど,n – m と m の大小関係は決定できないので3行目を入れた。これで m と n の大小関係も気にしなくて済んでいる。

相互再帰

2つ(あるいはそれ以上)の関数を and でつないでいっぺんに定義できるがおもしろい。

and の後の関数には let rec が要らない。

# let rec even n =
if n = 0 then true else odd (n - 1)
and odd n =
if n = 0 then false else even (n - 1)
;;
val even : int -> bool = <fun>
val odd : int -> bool = <fun>
# even 3;;
- : bool = false
# even 4;;
- : bool = true
# odd 5;;
- : bool = true
# odd 8;;
- : bool = false