Haskell 哪一种是首选的写作方法;卫兵;?
我已经创建了一个可以使用(据我所知)大小写表达式或保护的函数Haskell 哪一种是首选的写作方法;卫兵;?,haskell,Haskell,我已经创建了一个可以使用(据我所知)大小写表达式或保护的函数 foo a b c = case a of 1 -> [...] 2 -> [...] 3 -> [...] [...] otherwise -> error "..." 或 所以,问题是:这两个(外壳或防护装置)中哪一个是“更好”的
foo a b c = case a of 1 -> [...]
2 -> [...]
3 -> [...]
[...]
otherwise -> error "..."
或
所以,问题是:这两个(外壳或防护装置)中哪一个是“更好”的编码?两者基本相同吗?当一个保护可以在其中一个参数上重写为(无保护的)case语句时,实际上没有必要这样做。也就是说,你可以这样写:
foo 1 b c = [...]
foo 2 b c = [...]
foo 3 b c = [...]
[...]
哪一种是写它的首选方式。当您想要的条件无法表示为模式时,您会使用防护。当您需要匹配某个参数以外的其他参数时,可以使用case语句。第一个被认为是更好的样式,原因有二 首先:许多人会说它看起来更好,因为您不必键入所有的
=
。当然,这是一个非常主观的原因。此外,您通常甚至不会引入新的case语句,只需匹配函数参数列表中的参数,如下所示:
foo 1 b c = ... -- etc
...
foo _ b c = ... -- for the "otherwise" part
这使得代码更加紧凑和可读,这是许多人喜欢的
第二,实际上存在语义差异。假设您有这样一种数据类型:
data Cake = Apple | Cheese | Cream
| a == Apple = "fruit"
| otherwise = "not fruit"
如果使用第一种方法,则与表达式的case..中的构造函数匹配:
case a of
Apple -> "fruit"
_ -> "not fruit"
但是,如果您尝试执行某种类型的保护表达式,例如:
data Cake = Apple | Cheese | Cream
| a == Apple = "fruit"
| otherwise = "not fruit"
。。。它实际上不会工作,因为Cake
类型没有Eq
实例,所以不能使用==
来比较两个值。引入Eq
实例(在数据定义之后使用派生(Eq)
)并不总是需要的,因此在这种情况下不必这样做可能很重要。在第一个示例中,您不应该使用否则就不应该这样使用。它所做的是引入一个名为的新变量,否则=a
,这可能会导致微妙的错误。您应该改为执行\uuu->error“…”
。@dflemstr感谢您提供的信息和解释。作为一般的跨语言技巧,我更喜欢在下一行编写代码子块,并且始终使用相同的缩进级别。如果第一行的长度发生了变化(可能是因为foo被重命名或其他原因),这可以避免您必须重新删除其余的行。实际上,我有一些基本情况(我相信我可以称它们为基本情况–我是编码的初学者),比如“如果a==1&&b>c,那么(…)”。所以,如果应用您的建议,它可能会使我的代码可读性稍差,我想(?)。实际上(第2部分)。。。我想我能应用你的建议。。。看起来不错^^如果它们在语义上不同,你怎么能说一个比另一个更好?@AdamWagner因为在许多情况下,你可以选择使用结果完全相同的一个(通过“比较生成的机器代码”)。请注意,如果在函数定义中使用case语句而不是直接模式匹配,不同的案例可以共享相同的where
子句,就像警卫一样。