applyの定義

mapやreverse、append等の関数を定義しなさい、という練習問題はSchemeの本であればどれでも載せているようなものだけれども、applyを定義させるような問題はあまり見かけないように思う。もちろん、「SICPの4章5章あたりでevalと一緒に嫌というほど実装してるよ」っていうのはナシで。

というワケで実際に実装してみると、

(define (apply f args)
  ((fold (lambda (x f) (cut f x <...>))
         f
         args)))

という感じかな。
組込みのapplyのように可変個数の引数をとるようにするのであれば、

(define (apply f . args)
  ((fold (lambda (x f) (cut f x <...>))
         f
         (reduce-right cons '() args))))

だろか。効率は悪そう。


さて、ここでやっているのはリストの要素を先頭からカリー化することだけなのだから、カリー化の得意な言語で書けばもっと簡単に書けるんじゃないか、と思って勉強中のHaskellでも書いてみた。

apply f [] = f
apply f (x:xs) = apply (f x) xs

ところがこれはエラー。fの型が推論できないためらしい。そりゃそうだ、可変個数の引数をとる関数の型なんて決められない。

というか、よくよく考えてみれば、パターンマッチがあればリストをわざわざ分解して引数に渡す必要もないのか。Haskellはapplyの書きやすい言語どころかapplyの要らない言語だったのね…。