http://projecteuler.net/index.php?section=problems&id=40
遅延評価を使うと簡単です。
(fun k -> k <= N)
このラムダは、こう書けます。
((>=) N)
これは、(>=)は2つの引数を取る関数とみなせて、
(>=) N k
で、
N >= k
と同じになります。これをカリー化して上のようになります。
また、関数の合成というのがあって、例えば、1を足して2倍する、というのを分解して、
let f x = x + 1 let g x = x * x
これを次のように合成します。
let h = f >> g printfn "%d" (h 1) // 4
左から右にデータが流れるイメージです。
そうすると、
(fun x -> fst x = k)
は、
(fst >> ((=) k))
となります。ちょっとやりすぎですね。
open Seq let rec digits n = if n = 0 then [] else (digits (n / 10)) @ [n % 10] let count n = initInfinite ((+) 1) let s = seq { for n in count 1 do for d in digits n -> d } let d k = snd (head (filter (fst >> ((=) k)) (zip (count 1) s))) let N = 1000000 let seq_pow = takeWhile ((>=) N) (unfold (fun k -> Some(k, k * 10)) 1) printfn "%d" (fold (*) 1 (map d seq_pow))