8

シーケンスを使用して F# で Haskell の有名な無限フィボナッチ リストを模倣しようとしています。次のシーケンスが期待どおりに評価されないのはなぜですか? どのように評価されていますか?

let rec fibs = lazy (Seq.append 
                        (Seq.ofList [0;1]) 
                        ((Seq.map2 (+) (fibs.Force()) 
                                       (Seq.skip 1 (fibs.Force())))))
4

4 に答える 4

9

問題は、コードがまだ十分に遅延していないことです。Seq.append結果にアクセスする前に への引数が評価されますが、2 番目の引数 ( Seq.map2 ...) を評価するには、独自の引数を評価する必要があり、定義されているのと同じ遅延値が強制されます。これは、Seq.delay関数を使用して回避できます。lazyラッパーを放棄することもできます.slistはすでにseqsなので、必要ありませんSeq.ofList:

let rec fibs = 
    Seq.append [0;1]
        (Seq.delay (fun () -> Seq.map2 (+) fibs (Seq.skip 1 fibs)))

ただし、個人的には、シーケンス式を使用することをお勧めします.

let rec fibs = seq {
    yield 0
    yield 1
    yield! Seq.map2 (+) fibs (fibs |> Seq.skip 1)
}
于 2014-04-07T13:59:06.347 に答える
3

さらに別の方法:

let rec fib = seq { yield 0; yield! Seq.scan (+) 1 fib }
于 2014-04-08T05:59:40.100 に答える