言語ゲーム

とあるエンジニアが嘘ばかり書く日記

Twitter: @propella

Haskell で cons を実装してみる。

SICP 2.1.3 What It Meant by Data? の話です。関数型言語では、データ構造としてよくリストが使われます。しかし本当はリストですらプリミティブで無く、リストを関数で表現出来るという話です。しかも、これは関数型言語オブジェクト指向言語の面白い交差点になっています。まず scheme におけるリストの復習。

gosh> (define a (cons 3 4)) ;; 3 と 4 でリストを作る。
a
gosh> a
(3 . 4)
gosh> (car a) ;; 左側のオブジェクトを取り出す。
3
gosh> (cdr a) ;; 右側のオブジェクトを取り出す。
4

「リストとは、右側と左側の二つのポインタを持つ構造だ」というのが普通の考え方ですが、これを、「cons, car, cdr がそれぞれ上のように振舞うオブジェクトをリストと呼ぶ」という風に言い換える事が出来ます。中身を問わずにインタフェースで定義するわけです。これを Haskell で作ってみます。

cons a b "car" = a
cons a b "cdr" = b
car x = x "car"
cdr x = x "cdr"
*Main> let a = (cons 3 4)
*Main> (car (cons 3 4))
3
*Main> (cdr (cons 3 4))
4

簡単すぎてツマラン。。。と思ったら大きな落とし穴が。Haskell では、関数が返す型は一つと決まっていて、(cons 3 (cons 4 5))) のような事が出来ないのでした(3 と (cons 4 5) の型が違うので)。どーすれば良いのだ?!!