簡體   English   中英

F#遞歸行為

[英]F# recursion behavior

我最近開始學習F#,因為我對大多數功能概念都很陌生,所以我傾向於為自己寫一些小例子,並用測試結果檢查我的前提。

現在我似乎無法理解以下代碼的結果以及它為什么會這樣表現。 使用案例:我擲四個六面骰子,只有當它們的總和大於20時才返回它們的總數。

這是我的代碼:

let rnd = System.Random()
let d6 () = rnd.Next(1, 7)
let rec foo () =
    // create a list of 4 d6 throws and print out the list
    let numbers = seq { for i in 1 .. 4 -> d6() }
    numbers |> Seq.iter( fun n -> printf "%i " n )
    printfn "\n"

    // sum the list and return the sum only when the sum is greater than 20
    let total = numbers |> Seq.sum
    match total with
    | n when n < 21 -> foo ()
    | _ -> total

現在,當你運行它時,你會發現這最終會返回一個大於20的數字。

當您查看輸出時,您會發現它沒有打印出最后一個數字列表,我無法弄清楚原因。

序列被懶惰地評估並且不被高速緩存。 這里發生的是你有一個副作用的序列被多次評估。

第一次評估產生第一個隨機數序列:

numbers |> Seq.iter( fun n -> printf "%i " n )

第二個調用再次運行評估,產生完全不同的序列:

let total = numbers |> Seq.sum

如果要保持第一次評估以多次運行它,您需要做的是實現序列或緩存它:

// create a list directly
let numbers = [ for i in 1 .. 4 -> d6() ] 
// or create a list from sequence
let numbers = seq { for i in 1 .. 4 -> d6() } |> List.ofSeq
// or cache the sequence
let numbers = seq { for i in 1 .. 4 -> d6() } |> Seq.cache

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM