我为测试一些简单的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“和”b“。我想知道为什么这样出来?谢谢!
我为测试一些简单的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“和”b“。我想知道为什么这样出来?谢谢!
可能是因为在进行测试调用之前,printfn函数调用都会被评估吗?如果你希望这两个函数调用被推迟到实际使用之前,你可能需要lazy computation或宏(F#没有)。
郝正确。你必须在函数中包装这些表达式来使它们变得懒惰。尝试这个。
let test c a b = if c then a() else b();;
test true (fun() -> printfn "a") (fun() -> printfn "b");;
非常清楚,它是同样的原因,
let f x = x + 1
f (3+5)
调用f
前评估(3+5)
。除了Haskell外,几乎所有的语言都是这样工作的(带有宏的模态语言)。
这是一个懒惰的计算版本。 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 =()
>
感谢您的回复!在考虑呼叫之前进行评估,我希望我会看到输出为“a,b,a”,即将呼叫的结果添加到结尾。那么,没关系。这可能是F#现在的工作原理。 – Here 2010-06-11 16:21:54