For Development HEAD DRAFTSearch (procedure/syntax/module):

11.63 srfi.232 - 柔軟なカリー化された手続き

Module: srfi.232

このモジュールは、定義時に指定された仮引数よりも少なかったり多かったりする実引数を取れる 手続きを定義するマクロを提供します。 このマクロで定義された手続きが、仮引数よりも少ない実引数を渡された場合は、 部分適用となり、残りの引数を受け取る手続きが返されます。 もし仮引数よりも多い実引数が渡された場合、仮引数分の実引数が手続きにまず渡され、 その戻り値(手続きであることが期待されます)に残りの実引数が渡されます。

厳密な意味でのカリー化は、n引数の手続きをネストした1引数の手続きに変換することです。

(lambda (a b c) body)
  ⇒ (lambda (a) (lambda (b) (lambda (c) body)))

Schemeでは、この方法でカリー化された手続きにすべての引数を渡そうとすると、 括弧をネストしなければなりません。

(((f 1) 2) 3)

これに対し、このsrfiで作られる手続きには、複数の引数をまとめて渡すことができます。 以下の例で、fの呼び出しはすべて同じ動作となります。

(define-curried (f a b c) body)

(f 1 2 3)
(((f 1) 2) 3)
((f 1 2) 3)
((f 1) 2 3)

さらに、仮引数よりも多くの実引数をfに渡すことができます。ここで、 fは(追加の引数を取る)手続きを返すことが期待されています。 つまり、次のような等価性が成り立ちます。

(f 1 2 3 4 5 6) ≡ ((f 1 2 3) 4 5 6)
Macro: curried formals body …

[SRFI-232]{srfi.232} (lambda formals body …)と同じように手続きを作って返しますが、 作られた手続きはformalsで指定されるより少なかったり多かったりする引数を 取ることができます。

呼び出し時に渡される引数が過少な場合は、部分適用として動作し、 残りの引数を受け取る手続きが返されます。

(define f (curried (a b c d) (+ a b c d)))

(f 1 2 3 4) ⇒ 10        ; 通常の呼び出し
(f 1 2) ⇒ #<procedure>  ; 部分適用。(pa$ f 1 2)と同じ
((f 1 2) 3 4) ⇒ 10      ; 残りの引数を提供
(((f 1 2) 3) 4) ⇒ 10    ; 部分適用はネストでき、
(((f 1) 2 3) 4) ⇒ 10    ; ... また一回の呼び出しでいくつも引数を渡せる

また、formalsが「残余引数」を指定していなくても、返される手続きはformalsより 多くの引数を取ることができます。formalsが残余引数を取る場合は、 余分な実引数は残余引数として渡されます。そうでなければ、必要な引数だけが手続きにまず 渡され、その戻り値がもう一度、残りの引数とともに呼び出されます。

(define f (curried (a b c) (^[x] (* x (+ a b c)))))

(f 1 2 3 4) ⇒ 24  ; ≡ ((f 1 2 3) 4)

引数が渡されなかった場合は、手続き自身が返ります。

(((f)) 1 2 3) ≡ (f 1 2 3)

特別な場合として、 (curried () body)および(curried identifier body)は、それぞれ (lambda () body)および(lambda identifier body)と同じです。

Macro: define-curried (name . formals) body …

[SRFI-232]{srfi.232} (define name (curried formals body …))の略記です。



For Development HEAD DRAFTSearch (procedure/syntax/module):
DRAFT