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

标签 haskell lazy-evaluation

这个问题是出于对 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'` with
if' :: Bool -> a -> a -> a
if' True  x _ = x
if' False _ y = y


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

但是如果条件是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.

关于haskell - `if-then-else`(总是)可以被函数调用替换吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48355417/

相关文章:

haskell - 部分应用从左到右

haskell - 如何让 GHC 识别此代码片段中的 SingI 实例?

c++ - C++ 中的延迟评估包装类?

c# - 实现一个 "LazyProperty"类——这是个好主意吗?

haskell - 什么是单子(monad)类别的仿函数?

haskell - 一个函数,它接受一个列表并返回相同的列表,但不包含重复项

list - 倒转 [也许是] 横向行为

haskell - ByteString.Lazy.Char8(空间不足)

lazy-evaluation - 懒惰评估及其效率的澄清

functional-programming - Okasaki 的 Purely Functional Data Structure 中的 Streams 章节