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

微笑、不失礼 提交于 2019-12-24 00:56:41

问题


This question is out of curiousity about how PLs work, more than anything else. (It actually came to me while looking at SML which differs from Haskell in that the former uses call-by-value - but my question is about Haskell.)

Haskell (as I understand) has "call-by-need" semantics. Does this imply that if I define a function as follows:

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

that this will always behave exactly like an if-then-else expression? Or, in another sense, can if-then-else be regarded as syntactic sugar for something that could've been defined as a function?


Edit:

Just to contrast the behaviour of Haskell with Standard ML, define (in SML)

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

and then the factorial function

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

evaluating factc 1 (say) never finishes, because the recursion in the last argument of cond never terminates.

However, defining

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

works as we expect because the then branch is only evaluated as needed.

Maybe there are clever ways to defer argument evaluation in SML (don't know as I'm not that familiar with it yet) but the point is that in a call-by-value type language, if-then-else often behaves differently. My question was whether this (call-by-need vs call-by-value) was the principle reason behind this difference (and the consensus seems to be "yes").


回答1:


Like the Haskell Wikipedia on if-then-else says:

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

So if we use the above if' function, and we need to evaluate it (since Haskell is lazy, we do not necessary need to evaluate an if-then-else expression at all), Haskell will first evaluate the first operand to decide if it is True or False. In case it is True, it will return the first expression, if it is False it will return the second expression. Note that this does not per se means that we (fully) evaluate these expressions. Only when we need the result, we will evaluate the expressions.

But in case the condition is True, there is no reason at all to ever evaluate the second expression, since we ignore it.

In case we share an expression over multiple parts of the expression tree, it is of course possible that another call will (partially) evaluate the other expression.

ghci even has an option to override the if <expr> then <expr> else <expr> syntax: the -XRebindable flag. It will, besides other things also:

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




回答2:


Yes, a lazy language will evaluate an expression only when it needs to. Therefore it is no problem to convert the then/else parts of the expression into function arguments.

This is unlike strict languages like Idris or OCaml, where arguments for a function call are evaluated before the called function is executed.




回答3:


Yes, you can regard if/then/else as syntactic sugar. In fact, a programming language doesn't even need Boolean primitives, so you can also consider True and False as syntactic sugar.

The lambda calculus defines Boolean values as a set of functions that take two arguments:

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

Both functions are functions that takes two values, t for true, and f for false. The function true always returns the t value, whereas the function false always returns the f value.

In Haskell, you can define similar functions like this:

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

You could then write your cond function like:

cond = \b t f -> b t f

Examples:

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

Read more in Travis Whitaker's article Scrap Your Constructors: Church Encoding Algebraic Types.



来源:https://stackoverflow.com/questions/48355417/could-if-then-else-always-be-replaced-by-a-function-call

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!