OCamlやってみよう(2)
参考ページとか
- http://www.i.kyushu-u.ac.jp/~bannai/ocaml-intro/
- http://www.ocaml-tutorial.org/ocaml%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%81%AE%E6%A7%8B%E9%80%A0
- http://jijixi.azito.com/cgi-bin/diary/index.rb?date=19700102
- http://ocaml.jp/archive/document/
OCamlの関数っていうのは、Schemeで言う「引数を一つだけ取り、lambda式を一つだけ返す関数」なのかな。
gosh> (lambda (x) (lambda (y) (+ x y))) #<closure 009DDE40(x)> gosh> ((lambda (x) (lambda (y) (+ x y))) 2) #<closure 009DDE00(y)> gosh> (((lambda (x) (lambda (y) (+ x y))) 2) 3) 5
# fun a -> fun b -> a+b;; - : int -> int -> int = <fun> # (fun a -> fun b -> a+b) 2;; - : int -> int = <fun> # (fun a -> fun b -> a+b) 2 3;; - : int = 5
おんなじおんなじ。何か新しい概念を理解しようとしているときに、既存の概念を使いまわすのはあまりよくないと思うけど。ファミコンとプレステの区別がつかない大人になんてなりたくない。あとPCに詳しくない歳いった人に多い、わけのわからないPCへの理解の仕方を見たりするとつくづく、新しい概念を怖がっちゃいけないなと思う。余談。
そんなこととかをふまえて、階乗関数factをいくつかの方法で書いてみる。
# let rec f = fun a -> fun x -> if(x=0) then a else f (a*x) (x-1);; val f : int -> int -> int = <fun> # let fact = f 1;; val fact : int -> int = <fun> # fact 5;; - : int = 120
factの内部でしか使わないfを全体で束縛しちゃってるのが駄目っぽいすね。
# let fact = let rec f = fun a -> fun x -> if(x=0) then a else f (a*x) (x-1) in f 1;; val fact : int -> int = <fun> # fact 5;; - : int = 120
「let...in」で式をローカルで束縛できる。なんか怪しいような気がするけどまあいいや。
# let fact = (fun f -> fun a -> fun x -> f a x) (fun a -> fun x -> if(x=0) then a else f (a*x) (x-1)) 1;; val fact : int -> int = <fun> # fact 5;; - : int = 120
let recとか謎な機能使わずに無名の高階関数でやっちゃおうぜの巻。let recはシンタックスシュガーだ! 知らないけど。
funとfunctionは単なる略記形式じゃなくて別物らしい。