这个问题是出于对 PL 如何工作的好奇,而不是其他任何事情。 (它实际上是在查看与 Haskell 不同的 SML 时想到的,因为前者使用按值调用 - 但我的问题是关于 Haskell。)
Haskell(据我所知)具有“按需调用”语义。
这是否意味着如果我定义一个函数如下:
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 通常表现不同.
我的问题是这(按需要调用与按值调用)是否是这种差异背后的主要原因(并且共识似乎是"is")。
最佳答案
喜欢 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'` withif' :: Bool -> a -> a -> a if' True x _ = x if' False _ y = y
所以如果我们使用上面的
if'
函数,我们需要计算它(因为 Haskell 是惰性的,我们不需要计算 if
- then
- else
表达式),Haskell 将首先计算第一个操作数来决定它是否是True
或 False
.如果是 True
, 返回第一个表达式,如果是 False
它将返回第二个表达式。请注意,这本身并不意味着我们(完全)评估这些表达式。只有当我们需要结果时,我们才会评估表达式。但是如果条件是
True
,根本没有理由评估第二个表达式,因为我们忽略了它。如果我们在表达式树的多个部分共享一个表达式,那么另一个调用当然有可能(部分)评估另一个表达式。
ghci
甚至可以选择覆盖 if <expr> then <expr> else <expr>
语法: -XRebindable
旗帜。除了其他事情之外,它还将:Conditionals (e.g.
if e1 then e2 else e3
) meansifThenElse e1 e2 e3
. However case expressions are unaffected.
关于haskell - `if-then-else`(总是)可以被函数调用替换吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48355417/