如果我写:
> let xs = [1,5,19,2,-3,5]
> foldr max 0 xs
19
> foldr1 max xs
19
Run Code Online (Sandbox Code Playgroud)
如果我写(我知道,这里的初始值对于通用最大函数是不正确的......):
> let maximum' = foldr max 0
> maximum' xs
19
Run Code Online (Sandbox Code Playgroud)
但如果我写:
> let maximum2' = foldr1 max
> maximum2' xs
Run Code Online (Sandbox Code Playgroud)
回应是:
<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
Run Code Online (Sandbox Code Playgroud)
我是Haskell的新手.我究竟做错了什么?(无法破译的错误信息......)如何使用foldr1
与max
?谢谢.
编辑(接受答复后):
只是为了展示一些违约规则效果的例子(答案也解释了这些):
例1:
> let max' = max
> :t max
max :: Ord a => a -> a -> a
> :t max'
max' :: () -> () -> ()
Run Code Online (Sandbox Code Playgroud)
例2:
> let plus = (+)
> :t (+)
(+) :: Num a => a -> a -> a
> :t plus
plus :: Integer -> Integer -> Integer
Run Code Online (Sandbox Code Playgroud)
Nei*_*own 13
问题在于类型的多态性和GHCi的默认值.类型max
是多态的:
> :t max
max :: Ord a => a -> a -> a
Run Code Online (Sandbox Code Playgroud)
在这种情况下maximum'
,编译器可以看到这a
是某种数字,GHCi将数字默认为Integer:
> :t maximum'
maximum' :: [Integer] -> Integer
Run Code Online (Sandbox Code Playgroud)
如果maximum2'
它有较少的线索,默认a
为单位类型:
> :t maximum2'
maximum2' :: [()] -> ()
Run Code Online (Sandbox Code Playgroud)
如果您提供类型签名,一切都很好:
> let maximum3' :: Ord a => [a] -> a ; maximum3' = foldr1 max
> :t maximum3'
maximum3' :: Ord a => [a] -> a
Run Code Online (Sandbox Code Playgroud)
我认为GHCi的默认规则是为了使某些其他类型被省略的情况更容易 - 参见http://www.haskell.org/ghc/docs/7.6.2/html/users_guide/interactive-evaluation.html#id484837