[Haskell-beginners] type inference question

Daniel Fischer daniel.is.fischer at web.de
Sun Aug 23 14:44:25 EDT 2009

Am Sonntag 23 August 2009 20:12:16 schrieb I. J. Kennedy:
> Given a sort function that works on numbers, you can sort
> in reverse order by first negating the list, then sorting, then
> negating again:
>  Prelude Data.List> let revsort = (map negate) . sort . (map negate)
> The function sort takes any list of Ord; negate works on any Num.
>  Prelude Data.List> :t negate
>  negate :: (Num a) => a -> a
>  Prelude Data.List> :t sort
>  sort :: (Ord a) => [a] -> [a]
> I'd therefore expect my revsort function to work on any type that is
> both an Ord and a Num.  However:
> Prelude Data.List> :t revsort
> revsort :: [Integer] -> [Integer]
> I was expecting something like
>  revsort :: (Ord a, Num a) => [a] -> [a]
> instead.
> Question: Why did the GHCI's type inference mechanism jump to
> the conclusion that revsort should only work with Integer lists?

Because you defined it without an argument or type signature.
By the monomorphism restriction ( 
http://www.haskell.org/haskellwiki/Monomorphism_Restriction ), such values must have a 
monomorphic type and by the defaulting rules, that is chosen as Integer.

You can
a) specify a type signature (good in source files)
b) define it as a function binding
let revsort xs = map negate . sort . map negate $ xs
c) turn off the monomorphism restriction in ghci:
Prelude> :set -XNoMonomorphismRestriction
Prelude> :m +Data.List
Prelude Data.List> let revsort = map negate . sort . map negate
Prelude Data.List> :t revsort
revsort :: (Num a, Ord a) => [a] -> [a]
(might put :set -XNoMonomorphismRestriction in your .ghci file)

btw, another way to revsort is
let revsort = sortBy (flip compare)

More information about the Beginners mailing list