めざせ自然言語プログラミング by F#
Scalaだけ(http://d.hatena.ne.jp/tanakahisateru/20081208/1228742669)じゃ不公平なので、F#でも素数を求めてみました。
ワンライナーで書くとこんな感じ。
#light List.filter (fun n -> not (List.exists (fun m -> n % m = 0) [2..n-1]) ) [2..100];;
面白く書くとこんな感じ。
let of_only_which = List.filter let join_with sep xs = List.fold_left (fun s x -> s + sep + x.ToString()) ((List.hd xs).ToString()) (List.tl xs) (* (x :> obj).ToString()ではなくx.ToString()でOK *) let prime_factor_of n = (fun m -> n % m = 0) let is_not_in xs f = not (List.exists f xs) let lessor_nums_than n = [2..n-1] let is_prime_number n = (prime_factor_of n) |> is_not_in (lessor_nums_than n) System.Console.WriteLine( ([2..100] |> of_only_which is_prime_number) |> joined_with ",");;
英単語だけ順番に拾って、体裁を整えました。
Is prime number N? : Prime factor of N is not in lessor numbers than N.
2 .. 100 of only which is prime number joined with ",".
ま、これはやりすぎだとしても、関数と引数の記述順序を逆転できるのは便利っぽい。思考の順序のとおりに(もちろん一時変数なしで)書けるし、また、読めるし。
そうそう、(x :> obj).ToString()ではまりました。型推論上、ジェネリックな型となる変数は、明示的にobj型にダウンアップキャストしないとToString()メソッドが呼べないようです。どう考えてもキャスト要らないと思うんだけど…これってバグかな。
1.9.6.2では型推論がより強化されたようで、総称型xでobjに定義されたメソッドを呼ぶさい、(x :> obj).ToString()というような回りくどい表現は不要になりました。