* * *
* *"> *
* * *
Akihito Nagata's Page
|
|
Ocamlで関数を使うrakuda

関数の基本

Ocamlの関数は"fun"というキーワードを用いて定義される。最初に引数の名前の列が続き、そのあと"->"で区切られbody部分が書かれる。デフォルトでは関数には名前がつかない。名前をつけたいときはletを使う。
# let incr = fun i -> i + 1;;
val incr : int -> int = <fun>  
型の情報の"->"は関数であることをあらわしている。ここではint型の値を引数として受け取ってint型の値を返すという意味である。
# incr 2;;
- : int = 3
引数は複数指定することもできる。
# let sum = fun i j -> i + j;;
val sum : int -> int -> int = <fun>
# sum 3 4;;
- : int = 7
また関数には名前がつけられることが多いため、簡単に
# let sum i j = i + j;;
と書くこともできる。

ネストした関数

CやJavaと違ってOcamlは関数の中に関数を書くことができる。
# let sum i =
     let sum2 j =
        i + j
     in 
       sum2;;
val sum : int -> int -> int = <fun>
# sum 3 4;;
- : int = 7
ここで変数のスコープはletで定義された変数のスコープはそのbody部分である"in"の中、引数の変数のスコープはその関数のbody部分に限られる。ここで新に定義されたsumは先のsumと同じ動きをする。厳密にはOcamlには多引数関数というものはなく全てこのような1引数の関数に展開される(カリー化という)。つまりsumの型のint -> int -> intはint -> (int -> int)という意味である。
# let a = sum 1;;
val a : int -> int = <fun>
# a 3;;
- : int = 4

再帰関数

再帰した関数を定義するにはletの代わりにlet recを使う。
# let rec power i x =
  if  i = 0 then
      1
  else x * (power (i -1 ) x);;
      val power : int -> int -> int = <fun>
# power 2 3;;
- : int = 9
let recを使うと新に定義された変数のスコープがその値の定義部分でも参照することができるようになる。
相互再帰関数を定義したいときはandキーワードを用いる。
# let rec odd x =
    if x = 0 then false
             else even (x - 1)
  and even x = 
    if x = 0 then true
             else odd (x -1);;
val odd : int -> bool = <fun>
val even : int -> bool = <fun>
# odd 4;;
- : bool = false
# even 4;;
- : bool = true

高階関数

Ocamlでは関数も普通の値として扱うことができるため、関数を受け取るような関数を定義することができる。
# let double f x = f (f x);;
val double : ('a -> 'a) -> 'a -> 'a = <fun>
# double (sum 3) 1;;
- : int = 7
doubleは第1引数に引数をひとつ受け取る関数を受け取ってそれを第2引数に2回適用する関数である。sum 3は引数を受け取って3を加える関数とみることができるので第2引数の1に対して"3を足す"という動作が2回繰り返されるので値は7となる。

変数名について

ocamlの変数には英数字(大文字、小文字どちらでもOK)、"'"、"_"(アンダーバー)を使うことができる。ただし、小文字、もしくはアンダーバーから始まらなくてはならない。

中置演算子

+,*などは他の関数と違って中置記法(infix)で記述できる。他の関数と同様に前置記法で記述するにはかっこをつける。
# (+) 1 2;;
- : int = 3
# ( * ) 3 4;;
- : int = 12
*を前置で書くにはコメントと見なされないために、かっことの間にスペースを入れる必要がある。
また、
# let rec power x y = if y == 0 then 1 else x * power x (y - 1);;
val power : int -> int -> int = 
# let ( ** ) x y = power x y;;
val ( ** ) : int -> int -> int = 
# 3 ** 4;;
- : int = 81
のようにすると新しい中置演算子を作ることができる。
|
前のページはこちら