部分適用

久しぶりにSchemeを触った。
Gaucheが使いたかったので emacs + gauche + quack.el で環境を作ってみた。
やっぱりemacsは嫌いだなぁ。


さて、Schemeでの部分適用はこんな感じのようで。

cut

SRFI-26にcutというマクロがあるらしい。

gosh> ((cut * 10 <>) 5)
50

gosh> (define (foo a b c)
        (list a b c))
foo
gosh> ((cut foo <> 2 <>) 1 3)
(1 2 3)

<>の部分に値を渡す感じかな。
なので、2つ目の例のように任意の引数だけ部分適用できる。
ちなみにOcamlのラベル付き引数の部分適用でも同じようなことが出来ますね。

# let foo ~a ~b ~c = [a; b; c] ;;
val foo : a:'a -> b:'a -> c:'a -> 'a list = <fun>

# let a = foo ~b:2 ;;
val a : a:int -> c:int -> int list = <fun>
# a 1 3 ;;
- : int list = [1; 2; 3]

pa$ などなど

Gaucheには部分適用や関数合成用にも色々用意されているらしい。
6.16.1.2 コンビネータ

gosh> (map (pa$ expt 2) '(0 1 2 3 4 5))
(1 2 4 8 16 32)

gosh> (define my-func (compose (pa$ * 10) (pa$ + 3)))
my-func
gosh> (my-func 7)
100

gosh> (define bye-taro (remove$ (pa$ eq? 'taro)))
bye-taro
gosh> (bye-taro '(taro jiro hanako john taro thinkpad taro))
(jiro hanako john thinkpad)

Common Lispではこんなに美しく書けない・・・。
テクマクマヤコンテクマクマヤコン Common Lisp名前空間が1つになあれえ〜。