ラムダ式: fun キーワード
ラムダ式: fun キーワード Lambda Expressions: The fun Keyword
元ネタ http://msdn.microsoft.com/ja-jp/library/dd233201.aspx
ラムダ式、つまり匿名関数を定義するには、fun キーワードを使用します。
F#
// Lambda expressions with parameter lists. fun a b c -> ... fun (a: int) b c -> ... fun (a : int) (b : string) (c:float) -> ... // A lambda expression with a tuple pattern. fun (a, b) -> … // A lambda expression with a list pattern. fun head :: tail -> …
C# でも書き方は似ている。fun キーワードはいらない。
C#
// parameter lists and tuple pattern Func<int, string, float, int> f = (a, b, c) => 0; // list pattern はこんな感じ? Func<int, List<int>, int> f2 = (head, tail) => head + tail.Sum();
list pattern の場合は、head と tail を取り出せば良いので、こんな感じか?
expression は関数の本体であり、その最後の式によって戻り値が生成されます。 有効なラムダ式の例は次のとおりです。
F#
fun x -> x + 1 fun a b c -> printfn "%A %A %A" a b c fun (a: int) (b: int) (c: int) -> a + b * c fun x y -> let swap (a, b) = (b, a) in swap (x, y)
最後の swap は無理矢理 F# と同じように書くとこんな風になる。
C#
Func<int, int> f = x => x + 1; Func<object, object, object, object> f2 = (a, b, c) => { Console.WriteLine("{0} {1} {2}", a, b, c); return null; }; Func<int, int, int, int> f3 = (a, b, c) => a + b * c; Func<object, object, object> f4 = (x, y) => { Func<Tuple<object, object>, Tuple<object, object>> swap = (t) => { return new Tuple<object, object>(t.Item2, t.Item1); }; return swap(new Tuple<object, object>(x, y)); };
ただし、内部で swap 関数を作る必要がなければ、Tuple を返すだけでよい。
C#
Func<object,object,Tuple<object,object>> f5 = (a,b) => new Tuple<object,object>( b, a);
ラムダ式の使用
この場合は、匿名関数が、リストのすべての要素に 1 を追加します。
F#
let list = List.map (fun i -> i + 1) [1;2;3] printfn "%A" list
C# には map 関数がないので自作するのだが、次のように拡張メソッドで作れる。ただし、拡張メソッドでは T が使えないので int 型限定。C# 6.0 ではジェネリックが使える予定なハズ。
C#
void test3() { var lst = new List<int> { 1, 2, 3 }; var dest = lst.Map(x => x + 1); } public static class ListExtensions { public static List<int> Map( this List<int> src, Func<int,int> fn) { var dest = new List<int>(); foreach (var it in src) { dest.Add(fn(it)); } return dest; } }
適用関数とリストの順序を守って、ListEx という新しいクラスを作ると T で書ける。
C#
void test4() { var lst = new List<int> { 1, 2, 3 }; var dest = ListEx<int>.Map(x => x + 1, lst); } public class ListEx<T> { public static List<T> Map(Func<T, T> fn, List<T> src) { var dest = new List<T>(); foreach (T it in src) { dest.Add(fn(it)); } return dest; } }