`if-then-else`(总是)可以被函数调用代替吗?

Could `if-then-else` (always) be replaced by a function call?

这个问题是出于对 PL 是如何工作的好奇,而不是其他任何东西。 (它实际上是在查看与 Haskell 不同的 SML 时想到的,因为前者使用按值调用 - 但我的问题是关于 Haskell。)

Haskell (据我了解)具有 "call-by-need" 语义。 这是否意味着如果我定义一个函数如下:

cond True thenExp elseExp = thenExp 
cond _ thenExp elseExp = elseExp

这将始终表现得与 if-then-else 表达式完全一样? 或者,从另一种意义上说,if-then-else 是否可以被视为可以定义为函数的东西的语法糖?


编辑:

为了对比 Haskell 与标准 ML 的行为,定义(在 SML 中)

cond p t f = if p then t else f;

然后是阶乘函数

fun factc n = cond (n=0) 1 (n * factc (n-1));

评估 factc 1(比方说)永远不会完成,因为 cond 最后一个参数中的递归永远不会终止。

但是,定义

fun fact n = if n=0 then 1 else fact (n-1);

按我们预期的方式工作,因为 then 分支仅在需要时进行评估。

也许在 SML 中有推迟参数评估的聪明方法(不知道,因为我还不太熟悉)但关键是在按值调用类型的语言中,if-then -else 通常表现不同。 我的问题是这(按需调用与按值调用)是否是这种差异背后的主要原因(共识似乎是 "yes")。

是的,惰性语言只会在需要时才对表达式求值。因此,将表达式的 then/else 部分转换为函数参数是没有问题的。

这与 Idris 或 OCaml 等严格的语言不同,在这些语言中,函数调用的参数在执行被调用函数之前进行评估。

Haskell Wikipedia on if-then-else 所说:

For processing conditions, the `if-then-else` **syntax was defined in Haskell98**. However it could be simply replaced by the function `if'` with
if' :: Bool -> a -> a -> a
if' True  x _ = x
if' False _ y = y

所以如果我们使用上面的 if' 函数,我们 需要评估它 (因为 Haskell 是惰性的,我们不需要评估 if-then-else 表达式),Haskell 将首先评估第一个操作数以确定它是 True 还是 False.如果是True,它将return第一个表达式,如果是False,它将return第二个表达式。请注意,这本身 not 意味着我们(完全)评估这些表达式。只有当我们需要结果时,我们才会计算表达式。

但如果条件是 True,则根本没有理由计算第二个表达式,因为我们忽略了它。

如果我们在表达式树的多个部分共享一个表达式,另一个调用当然有可能(部分)计算另一个表达式。

ghci 甚至可以选择覆盖 if <expr> then <expr> else <expr> 语法:-XRebindable 标志。它会,除此之外还有:

Conditionals (e.g. if e1 then e2 else e3) means ifThenElse e1 e2 e3. However case expressions are unaffected.

是的,你可以把if/then/else当成语法糖。事实上,编程语言甚至不需要布尔值,所以你也可以把TrueFalse当作语法糖。

lambda calculus 将布尔值定义为一组带有两个参数的函数:

true = λt.λf.t
false = λt.λf.f

这两个函数都是取两个值的函数,t代表truef代表false .函数 true 总是 returns t 值,而函数 false 总是 returns f 值。

在Haskell中,你可以这样定义类似的函数:

true  = \t f -> t
false = \t f -> f

然后您可以像这样编写 cond 函数:

cond = \b t f -> b t f

示例:

Prelude> cond true "foo" "bar"
"foo"
Prelude> cond false "foo" "bar"
"bar"

阅读 Travis Whitaker 的文章 Scrap Your Constructors: Church Encoding Algebraic Types