foldr vs foldr1 usage in Haskell

2020-08-26 02:54发布

问题:

If I write:

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

> foldr1 max xs
19

And if I write (I know, the initial value is incorrect here for a generic maximum function...):

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

But if I write:

> let maximum2' = foldr1 max
> maximum2' xs

the response is:

<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

I am new to Haskell. What am I doing wrong? (Can't decipher the error message...) How to use foldr1 with max? Thanks.

EDIT (AFTER ACCEPTING ANSWER):

Just to show some more examples of the defaulting rules' effect (the answer explains these, too):

Example 1:

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

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

Example 2:

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

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

回答1:

The problem is to do with the polymorphism of the types and GHCi's defaulting. The type of max is polymorphic:

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

In the case of maximum', the compiler can see that a is some sort of number, and GHCi defaults the number to Integer:

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

In the case of maximum2' it has less clues, and defaults a to the unit type:

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

If you provide a type signature, all is well:

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

I think GHCi's defaulting rules are there to make certain other cases where the types are omitted easier -- see http://www.haskell.org/ghc/docs/7.6.2/html/users_guide/interactive-evaluation.html#id484837



标签: haskell