MultiWayIf和经典后卫有什么区别?

时间:2019-02-13 15:57:25

标签: if-statement haskell

MultiWayIf扩展提供了哪些功能,而使用|卫队则无法完成,反之亦然?

例如,一个人可以编写与

相同的功能
f x | x == 0 = -1
    | otherwise = x

f x = if | x == 0 -> -1
         | otherwise -> x

除了使用语法糖外,这两个示例之间没有任何区别。在某些情况下,我应该优先选择另一个吗?

3 个答案:

答案 0 :(得分:8)

多路if不应代替使用功能后卫。如果可以使用防护罩,则应该这样做。但是多行if也可以在表达式的中间使用,就像case一样,例如:

f x = "The argument is " ++ 
         if | x > 0 -> "positive"
            | x < 0 -> "negative"
            | otherwise -> "zero"

我个人确实认为此特定示例的清晰度令人怀疑,但这是有区别的。

答案 1 :(得分:3)

假设您有一个像{p>

if

if c1 then a1 else if c2 then a2 else if c3 then a3 else if c4 then a4 else if c5 then a5 else a6 可让您更简洁地编写为

MultiWayIf

此外,尽管每个if | c1 -> a1 | c2 -> a2 | c3 -> a3 | c4 -> a4 | c5 -> a5 | otherwise -> a6 表达式都必须提供一个条件值是true还是false的值(if不是有效的if c then a表达式,因为缺少if ),多向else不必详尽无遗; if可以省略。这只是句法上的放松;如果没有一个条件为真,则对表达式求值后仍然会引发异常。

答案 2 :(得分:2)

正如其他人所解释的,这实际上只是语法上的便利。您可以非常轻松地将任何多路if转换为等效的case表达式。

if
  | c1 -> e1
  | c2 -> e2
  ...

等同于

case () of
  _ | c1 -> e1
    | c2 -> e2
    ...

与往常一样,()的意思是“这里没什么可看的”,而_的意思是“而且我们什么也没看。”