第一种方法没问题。
第二个不断重复相同的数字对。

我很不清楚为什么......你能指出好的方向吗?

module Normal =
   let rnd = new MersenneTwister()
   let sampleNormal =
      fun () -> let rec randomNormal() = let u1, u2 = rnd.NextDouble(),rnd.NextDouble()
                                         let r, theta= sqrt (-2. * (log u1)), 2. * System.Math.PI * u2
                                         seq { yield r * sin theta; yield r * cos theta ; printfn "next";yield! randomNormal() }
                randomNormal()

   let sampleNormalBAD =
      fun () -> let rec randomNormal = let u1, u2 = rnd.NextDouble(),rnd.NextDouble()
                                       let r, theta= sqrt (-2. * (log u1)), 2. * System.Math.PI * u2
                                       seq { yield r * sin theta; yield r * cos theta ; printfn "next";yield! randomNormal }
                randomNormal

Normal.sampleNormal() |> Seq.take(10) |>Seq.toArray
Normal.sampleNormalBAD() |> Seq.take(10) |>Seq.toArray

最佳答案

在第一个示例中 randomNormal() 是一个函数,它接受 () 并返回一个值,每次都会对其进行评估。
在第二个 randomNormal 是一个值,所以它不会被评估两次,一旦有界,它将保持相同的值。

如果您翻转 randomNormal() 签名是:

unit->seq<float>

对于 randomNormal 只是:
seq<float>

更新:它继续打印,因为 printfn 在序列内,这是有界值。
如果您尝试在最后一行之前在正文中打印,您将看到不同之处。这是一个简化的示例代码:
let sampleNormal =
    fun () ->
        let rec randomNormal() =
            let u1, u2 = 1,2
            printfn "Evaluating"
            seq { yield u1; yield u2 ; printfn "next";yield! randomNormal() }
        randomNormal()

let sampleNormalBAD =
    fun () ->
        let rec randomNormal =
            let u1, u2 = 1,2
            printfn "Evaluating"
            seq { yield u1; yield u2 ; printfn "next";yield! randomNormal }
        randomNormal

关于recursion - F#中的递归函数与递归变量,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11285286/

10-09 21:08