リストのカリー化
(a b c d)というリストが与えられたら、(((a b) c) d)というリストに変換する関数とその逆をする関数を作ってみた。
カリー化すると必ず2要素のリストになるので、リストの構造的には、(((a . b) . c) . d)にする方が無駄がないのかもしれないけど、個人的好みにより前者を採用。
(use util.match) (define (curry l) (if (pair? l) (currys (reverse l)) l)) (define currys (match-lambda ((x) (curry x)) ((x . xs) `(,(currys xs) ,(curry x))))) (define (uncurry l) (if (pair? l) (uncurrys l) l)) (define uncurrys (match-lambda ((xs x) `(,@(uncurrys xs) ,(uncurry x))) ( x `( ,(uncurry x))))) #?=(uncurry #?=(curry #?='(a b c d))) #?=(uncurry #?=(curry #?='(a b c (a b c) a b c)))
実行結果
#?- (a b c d) #?- (((a b) c) d) #?- (a b c d) #?- (a b c (a b c) a b c) #?- ((((((a b) c) ((a b) c)) a) b) c) #?- (a b c (a b c) a b c)