Shammer's Philosophy

My private adversaria

OCamlの引数の処理のされ方

たとえば、int 型の引数を2つ受け取る関数があるとする。こんな感じ。

# let add x y = x + y;;
val add : int -> int -> int = <fun>
# add 10 20;;
- : int = 30
# 

この場合は、add の型は int -> int -> int = となる。意味としては、int 型の変数を2つ受け取り、int 型の戻り値を返す add という関数、ということになると思うが。最後のは関数だという意味だろう。

一方、以下のように書くと型が異なる。

# let add (x, y) = x + y;;
val add : int * int -> int = <fun>
# add 3 8;;
Error: This function is applied to too many arguments;
maybe you forgot a `;'
# add (3, 8);;
- : int = 11
# 

型が int -> int から、int * int になった。引数もカッコで渡してやらないとエラーになる。この違いは、引数を一つずつ渡すか一度に渡すか、という違いがあるようだ。別の言い方をすると、引数は一つずつ評価される、とでもいうことができるだろうか。たとえば

# let test x y z = x * 10 + y * 15 + z * 5;;
val test : int -> int -> int -> int = <fun>
# test 4 5 6;;
- : int = 145
# 

という例だと、

  1. test 4 5 6
  2. 4 * 10 + y * 15 + z * 5
  3. 40 + y * 15 + z * 5
  4. 40 + 5 * 15 + z * 5
  5. 40 + 75 + z * 5
  6. 以下略

というような感じのような・・・一度にすべての引数が渡されずに、引数を一つだけ評価されて、その評価後に次の引数が評価されて・・・というような感じで処理が進むようだ。何冊かしかない本を読むと、これに似た処理の流れが説明されている。関連はわからないけれど、こういう風に評価されるのか、とわかっていると後で何か役に立つのかもしれない。。。