Lambda

ラムダ式です。

funとの違いは、引数の受け取りに多値代入と同じルールが使われるという点です。

つまり、

foo : |x, y| x + y;
foo(1, 2).p;

は、

fun foo(X){x, y : X; return x + y;}
foo((1, 2)).p;

とだいたい同じ意味を持ちます。

ラムダ式では、引数が少ない場合には最後の引数がundefinedになってランタイムエラーにならないのに比べて、関数では引数が足りないのでランタイムエラーとなります。
また、多い場合にもラムダ式は最後の引数が多値になるのに比べて、関数では引数が多いのでランタイムエラーとなります。

Example

foo : |x, y| x + y;
foo(10, 20).p;

基本的には1つの式しか書くことができず、returnせずともその評価値が戻り値として使われますが、次のように{}とreturnを使って複数式を記述することもできます。この場合にはreturnしないとundefinedが返る(値が返らない)ので注意してください。

foo : |x, y|{
    X : x + 10;
    Y : y + 10;
    return X + Y;
};
foo(10, 20).p;

ラムダ式といえば再帰表現ですよね! {}を使わない場合は三項演算子を使って条件分岐します。

fact : |x, y|((x==1)? y: fact(x-1, (y?y*x:x)));
fact(5).p;

多値の結合(このプログラムだと末尾がundefinedな多値を結合しようとするとうまくいきませんが!)

sub_cat : |v, hd, tl|(tl? sub_cat(sub_cat(v, tl), hd): (v? (|x|x)(hd,v): hd));
cat : |l| sub_cat(null, l);
 
cat(((1, 2), 3), (3, 4, (5, 9))).p;

完全に愚かですが多値のマージソートを書きました。思ったよりも速かったですがやっぱり遅かったです。

pack : |x| x;
head : |hd, tl| hd;
tail : |hd, tl| tl;
is_list : |l| l.class===Values&&l.size()>1;
 
split_pack : |d, hd, tl| pack(pack(d, hd), tl);
split : |n, hd, tl|(n==0? pack(hd, tl): split_pack(hd, split(n-1, tl)));
merge_lr : |left, right| (head(left)<head(right))? pack(head(left), merge(tail(left), right)):
                                                   pack(head(right),merge(left, tail(right)));
merge_l : |left, right| pack(head(left), merge(tail(left), right));
merge_r : |left, right| pack(head(right), merge(left, tail(right)));
merge : |left, right| (left&&right)? merge_lr(left, right):
                                     (left? merge_l(left, right): (right? merge_r(left, right): ()));
sort_2nd : |left, right| merge(sort(left), sort(right));
sort_split : |hd, tl, tl2| tl2? pack(hd, sort_split(tl,tl2)): pack(hd,tl);
sort : |l| (is_list(l)? sort_split(sort_2nd(split(l.size()/2-1, l))): l);
reference/lambda.txt · 最終更新: 2011/06/28 14:00 by sukai
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0