我已经创建了一个函数,我可以使用(据我所知)案例表达或守卫.
foo a b c = case a of 1 -> [...]
2 -> [...]
3 -> [...]
[...]
otherwise -> error "..."
Run Code Online (Sandbox Code Playgroud)
要么
foo a b c | a == 1 = [...]
| a == 2 = [...]
| a == 3 = [...]
| [...]
| otherwise = error "..."
Run Code Online (Sandbox Code Playgroud)
所以,问题是:那两个(案件或警卫)中的哪一个是"更好"的编码?两者基本相同吗?
dfl*_*str 13
第一个被认为是更好的风格,原因有两个.
首先:很多人会说它看起来更好,因为你不必输入所有的==.当然,这是一个非常主观的原因.此外,您通常不会引入新的case语句,但只需匹配函数参数列表中的参数,如下所示:
foo 1 b c = ... -- etc
...
foo _ b c = ... -- for the "otherwise" part
Run Code Online (Sandbox Code Playgroud)
这使得代码更加紧凑和可读,这是许多人喜欢的.
其次,实际上存在语义差异.想象一下,你有这样的数据类型:
data Cake = Apple | Cheese | Cream
Run Code Online (Sandbox Code Playgroud)
如果使用第一个方法,则匹配case..of表达式中的构造函数:
case a of
Apple -> "fruit"
_ -> "not fruit"
Run Code Online (Sandbox Code Playgroud)
但是,如果你尝试做某种类型的保护表达式,如下所示:
| a == Apple = "fruit"
| otherwise = "not fruit"
Run Code Online (Sandbox Code Playgroud)
...它实际上不起作用,因为Cake类型没有Eq实例,所以你不能==用来比较两个值.引入Eq实例(deriving (Eq)在数据定义之后)并不总是需要,因此在这种情况下不必执行此操作可能很重要.
当一个警卫可以被重写为其中一个参数的(无保护)案例陈述时,它并不是真正必要的.即你可以把它写成:
foo 1 b c = [...]
foo 2 b c = [...]
foo 3 b c = [...]
[...]
Run Code Online (Sandbox Code Playgroud)
这是写它的首选方式.当您想要的条件不能表示为模式时,您将使用警卫.当你需要匹配除其中一个参数之外的东西时,你会使用case语句.
| 归档时间: |
|
| 查看次数: |
274 次 |
| 最近记录: |