Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# &引用;如果;表达问题_F# - Fatal编程技术网

F# &引用;如果;表达问题

F# &引用;如果;表达问题,f#,F#,我为“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”。我想知道为什么会这样?谢谢 可能是因为两个printfn函数调

我为“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”。我想知道为什么会这样?谢谢

可能是因为两个printfn函数调用都是在测试调用发生之前计算的?如果希望两个函数调用都延迟到实际使用为止,则可能需要或宏(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 = ()
>
>让测试c a b=if c then(a:Lazy).Force else(b:Lazy.Force;;
val测试:布尔->懒惰->懒惰->(单位->单位)
>测试为真(lazy(printfn“a”))(lazy(printfn“b”)();;
A.
val it:unit=()
>

感谢您的回复!考虑到调用之前的评估,我希望将输出视为“a,b,a”,即将调用结果添加到末尾。好吧,没关系。这可能就是F#目前的工作方式。