您可以将守卫视为 if 语句的语法糖。守卫中的表达式可以是任何有效的布尔表达式,就像在 if 语句中一样。这意味着您可以使用范围内的任何值和函数。
例如,您可以重写以下内容:
foo x | abc = ...
| def = ...
| otherwise = ...
作为
foo x = if abc then ... else if def then ... else ...
case
我们也可以用而不是更详细地写这个if
:
foo x = case abc of
True -> ...
False -> case def of
True -> ...
False -> ...
毕竟,if
它本身只是一个案例的语法糖!将所有内容都写成case
可以更容易地了解不同的功能如何只是同一事物的语法糖。
即使条件引用现有变量 ( abc
and def
) 而不是函数参数,第二个表达式显然也有意义x
;守卫只是以同样的方式工作。
你的例子有点复杂,因为它使用了一个名为"pattern guards"的扩展。这意味着守卫可以不仅仅是一个布尔值——它还可以尝试匹配一个模式。如果模式匹配,则守卫成功(例如,与带有 的守卫相同True
);否则,守卫无法匹配(就像getting 一样False
)。
我们可以想象将其重写为:
readPoint s | Just [x, y] <- matchRegex (mkRegex "...") s = ...
| otherwise = ...
作为
readPoint s = case matchRegex (mkRegex "...") s of
Just [x, y] -> ...
_ -> ...
case
您可以看到这与普通守卫版本之间的相似之处。模式守卫只是将脱糖扩展到任意模式,而不仅仅是布尔值。
同样,我相信您会同意在语句中允许任何表达式是有意义的case
——没有理由将其限制为使用函数的参数。守卫也是如此,因为它们实际上只是语法糖。