2010-06-09 54 views
4

我为测试一些简单的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“。我想知道为什么这样出来?谢谢!

+0

感谢您的回复!在考虑呼叫之前进行评估,我希望我会看到输出为“a,b,a”,即将呼叫的结果添加到结尾。那么,没关系。这可能是F#现在的工作原理。 – Here 2010-06-11 16:21:54

回答

6

可能是因为在进行测试调用之前,printfn函数调用都会被评估吗?如果你希望这两个函数调用被推迟到实际使用之前,你可能需要lazy computation或宏(F#没有)。

7

郝正确。你必须在函数中包装这些表达式来使它们变得懒惰。尝试这个。

let test c a b = if c then a() else b();; 
test true (fun() -> printfn "a") (fun() -> printfn "b");; 
4

非常清楚,它是同样的原因,

let f x = x + 1 
f (3+5) 

调用f前评估(3+5)。除了Haskell外,几乎所有的语言都是这样工作的(带有宏的模态语言)。

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 =() 
>