生成无限的项目列表并不会暂停"获得外部输入时

时间:2015-02-07 04:18:25

标签: f#

我有一些代码,当它要求用户输入时,我希望暂停。但是,如果最后一个表达式是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#很新,我已经花了太多时间在这上面。想知道发生了什么:)

1 个答案:

答案 0 :(得分:3)

如果你在F#interactive中尝试这段代码,你会看到不同的效果,具体取决于你的执行方式。

例如,如果你一次性执行它,它将创建值,但由于Seq.initInfinite指令丢失了,所以不会执行任何操作。我的意思是,不要让任何东西束缚,同时又是一个懒惰的表达,所以它的副作用不会被执行。如果删除最后一条指令,它将开始提示,因为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并清楚原因,这是因为它返回最后一个表达式不是Seq.initInfinite因为它懒惰而被忽略而丢失。

如果您移除printfn,它将成为&#39;返回值&#39;你的函数,所以在调用函数时会对它进行评估。