在Haskell中使用foldr vs foldr1

时间:2013-09-06 15:59:11

标签: haskell

如果我写:

> let xs = [1,5,19,2,-3,5]
> foldr max 0 xs
19

> foldr1 max xs
19

如果我写(我知道,这里的初始值对于通用最大函数是不正确的......):

> let maximum' = foldr max 0
> maximum' xs
19

但如果我写:

> let maximum2' = foldr1 max
> maximum2' xs

回复是:

<interactive>:61:11:
    Couldn't match expected type `()' with actual type `Integer'
    Expected type: [()]
      Actual type: [Integer]
    In the first argument of maximum2', namely `xs'
    In the expression: maximum2' xs

我是Haskell的新手。我究竟做错了什么? (无法解密错误消息...)如何将foldr1max一起使用?感谢。

编辑(接受答复后):

只是为了展示一些违约规则效果的例子(答案也解释了这些):

示例1:

> let max' = max
> :t max
max :: Ord a => a -> a -> a

> :t max' 
max' :: () -> () -> ()

示例2:

> let plus = (+)
> :t (+)
(+) :: Num a => a -> a -> a

> :t plus 
plus :: Integer -> Integer -> Integer

1 个答案:

答案 0 :(得分:13)

问题在于类型的多态性和GHCi的默认值。 max的类型是多态的:

> :t max
max :: Ord a => a -> a -> a

maximum'的情况下,编译器可以看到a是某种数字,GHCi将数字默认为Integer:

> :t maximum'
maximum' :: [Integer] -> Integer

对于maximum2',它的线索较少,默认值a为单位类型:

> :t maximum2'
maximum2' :: [()] -> ()

如果您提供类型签名,一切都很好:

> let maximum3' :: Ord a => [a] -> a ; maximum3' = foldr1 max
> :t maximum3'
maximum3' :: Ord a => [a] -> a

我认为GHCi的默认规则是为了使某些其他类型被省略的情况更容易 - 请参阅http://www.haskell.org/ghc/docs/7.6.2/html/users_guide/interactive-evaluation.html#id484837