获取外部输入时生成无限项列表不会 "pause"

Generating an infinite list of items does not "pause" when getting external input

我有一些代码,我希望在它要求用户输入时暂停。但是,如果最后一个表达式是 Seq.initInfinite.

,它只会执行此操作
let consoleaction (i : int) =
      Console.WriteLine ("Enter Input: ")
      (Console.ReadLine().Trim(), i)

Seq.initInfinite (fun i -> consoleaction i) |> Seq.map (fun f -> printfn "%A" f)

printfn "foo" // program will not pause unless this line is commented out.

对 F# 很陌生,我已经在这上面花了太多时间。想知道发生了什么:)

如果您在 F# 交互式中尝试这段代码,您将看到不同的效果,具体取决于您如何执行它。

例如,如果你一次执行它,它会创建值,但不会执行任何内容,因为 Seq.initInfinite 指令是 'lost' 我的意思是,不让绑定到任何东西,同时time 是一个惰性表达式,所以它的副作用不会被执行。如果你删除最后一条指令,它会开始提示,那是因为 fsi 绑定到 it 最后一个表达式,所以为了向你显示 it 的值,它开始计算 seq 表达式。

如果将它放在函数中,情况会有所不同,例如:

open System
let myProgram() =
    let consoleaction ...

现在您将在 Seq.initInfinite:

上收到警告
warning FS0020: This expression should have type 'unit', but has type
'seq<unit>'. Use 'ignore' to discard the result of the expression, or 
'let' to bind the result to a name.

说的很清楚了。除了 ignore 之外,警告建议您可以将 Seq.map 更改为 Seq.iter,因为您对地图的结果不感兴趣,这将是一系列单位。

但是现在你的程序将不会执行(尝试 myProgram())除非你删除最后一行 printfn 并且很清楚为什么,这是因为它 returns 最后不是 Seq.initInfinite 的表达式,因为它是懒惰的并且被忽略了。

如果您删除 printfn,它将成为您函数的 'return value',因此将在调用函数时对其求值。