模式匹配与警卫混合

Ste*_*and 9 haskell pattern-matching

我想定义函数:

accumulate_list' :: Num a => [a] -> ( a -> a -> a ) -> a
accumulate_list' l f 
    | [] f = 0
    | (x:xs) f = f x (accumulate_list xs f)
Run Code Online (Sandbox Code Playgroud)

但它没有编译,抱怨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
Run Code Online (Sandbox Code Playgroud)

它编译得很好,并且sum如果在参数中传递的功能是,那就像在列表上那样(+).是的,我终于发现,我想要实现的确实已经作为sum功能存在于Prelude中.

但是,我不明白为什么带有混合防护和模式匹配的第一个版本无法编译.问题是什么 ?

Sib*_*ibi 25

这是因为警卫基本上是一个布尔表达式.他们必须评估为TrueFalse.这样的事情应该是类似的:

accumulate_list' :: (Eq a, Num a) => [a] -> ( a -> a -> a ) -> a
accumulate_list' l f 
    | l == [] = 0
    | otherwise = undefined -- fill out undefined
Run Code Online (Sandbox Code Playgroud)

值得一提的是,自从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
Run Code Online (Sandbox Code Playgroud)

  • 提交了一个编辑,以添加有关模式保护的信息. (4认同)