我想定义函数:
accumulate_list' :: Num a => [a] -> ( a -> a -> a ) -> a
accumulate_list' l f
| [] f = 0
| (x:xs) f = f x (accumulate_list xs f)
但它没有编译,提示 x, xs, x, xs, 不在范围内。
为了达到同样的效果,我定义了这个函数
accumulate_list :: Num a => [a] -> ( a -> a -> a ) -> a
accumulate_list [] f = 0
accumulate_list (x:xs) f = f x $ accumulate_list xs f
它编译得很好,并且确实喜欢
sum
如果传入参数的函数是(+)
,则在列表中.是的,我终于发现我想要实现的目标确实已经在 Prelude 中作为 sum
存在。功能。但是,我不明白为什么混合防护和模式匹配的第一个版本无法编译。问题是什么 ?
最佳答案
这是因为守卫基本上是一个 bool 表达式。他们必须评估为 True
或 False
.像这样的东西应该类型检查:
accumulate_list' :: (Eq a, Num a) => [a] -> ( a -> a -> a ) -> a
accumulate_list' l f
| l == [] = 0
| otherwise = undefined -- fill out undefined
还值得一提的是,自从 Haskell 2010 中添加了模式防护以来,您可以像这样混合模式和防护:
accumulate_list' :: (Eq a, Num a) => [a] -> ( a -> a -> a ) -> a
accumulate_list' l f
| [] <- l = 0 --pattern for the empty list case
| 10 < 5 = 10 --arbitrary regular guard just because
| (x:xs) <- l = undefined --pattern for the non-empty case
关于haskell - 模式匹配与 guard 混合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25493757/