2010-06-09 14 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 =() 
>