我有一些代码,当它要求用户输入时,我希望暂停。但是,如果最后一个表达式是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#很新,我已经花了太多时间在这上面。想知道发生了什么:)
答案 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;你的函数,所以在调用函数时会对它进行评估。