2013-09-06 14 views
9

Se scrivo:foldr vs utilizzo foldr1 in Haskell

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

> foldr1 max xs 
19 

E se scrivo (lo so, il valore iniziale è errato qui per una funzione di massima generica ...):

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

Ma se scrivo:

> let maximum2' = foldr1 max 
> maximum2' xs 

la risposta è:

<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 

Sono nuovo di Haskell. Che cosa sto facendo di sbagliato? (Impossibile decifrare il messaggio di errore ...) Come usare foldr1 con max? Grazie.

EDIT (dopo aver accettato RISPOSTA):

solo per mostrare alcuni altri esempi di effetto delle regole inadempienti (la risposta spiega questi, anche):

Esempio 1:

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

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

Esempio 2:

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

> :t plus 
plus :: Integer -> Integer -> Integer 
+7

La temuta restrizione monomorfismo. – augustss

+1

abbastanza divertente ': t foldr1 max' dà' Ord a => [a] -> a' e 'let maximum 'l = foldr1 max l' funziona come previsto – soulcheck

+3

@augusts manca il collegamento a [restrizione monomorfismo] (http://www.haskell.org/haskellwiki/Monomorphism_restriction) – soulcheck

risposta

13

Il problema ha a che fare con il polimorfismo dei tipi e l'impostazione predefinita di GHCi. Il tipo di max è polimorfico:

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

Nel caso maximum', il compilatore può vedere che a è una sorta di numero, e le impostazioni predefinite GHCi numerici per intero:

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

Nel caso di maximum2' ha meno indizi, e di default a al tipo di unità:

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

Se provid e una firma tipo, tutto va bene:

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

Penso regole inadempienti di GHCi sono lì per fare alcuni altri casi in cui i tipi sono omessi più facile - vedono http://www.haskell.org/ghc/docs/7.6.2/html/users_guide/interactive-evaluation.html#id484837

+0

Wow! Risposta molto utile, grazie! E anche il collegamento è molto utile! – TFuto