我为“if”表达式测试了一些简单的F#代码,但结果对我来说意外:
> let test c a b = if c then a else b;;
val test : bool -> 'a -> 'a -> 'a
然而
> test true (printfn "a") (printfn "b");;
a
b
val it : unit = ()
我希望只打印出“a”,但在这里我得到了“a”和“b”。我想知道为什么会出现这种情况?谢谢!
答案 0 :(得分:7)
郝是对的。你必须将这些表达式包装在函数中以使它们变得懒惰。试试这个。
let test c a b = if c then a() else b();;
test true (fun () -> printfn "a") (fun () -> printfn "b");;
答案 1 :(得分:6)
可能是因为在测试调用发生之前都会对两个printfn函数调用进行求值?如果您希望将函数调用延迟到实际使用之后,您可能需要lazy computation或宏(F#没有)。
答案 2 :(得分:4)
非常清楚,这是出于同样的原因
let f x = x + 1
f (3+5)
在致电(3+5)
之前评估f
。除了Haskell之外,几乎所有语言都是这样的(带有宏的模数语言)。
答案 3 :(得分:0)
这是一个懒惰的计算版本。 F#似乎需要类型注释才能在这里使用Force方法。有点乱,但确实有效。
> let test c a b = if c then (a:Lazy<unit>).Force else (b:Lazy<unit>).Force;;
val test : bool -> Lazy<unit> -> Lazy<unit> -> (unit -> unit)
> test true (lazy (printfn "a")) (lazy (printfn "b"))();;
a
val it : unit = ()
>