I've a beginner's question about types in Haskell: Having a function like:
f i xs = (sort xs) !! i
How do I define the function f0 xs = f 0 xs
without explicit use of xs?
Just taking
f0 = f 0
does not work...
ghci shows me the folling types:
f :: Ord a => Int -> [a] -> a
f0 :: [()] -> ()
But ":t f 0" gives f 0 :: Ord a => [a] -> a
.
Why is that? Why do I get this type for f0? Why is there any difference between the type of "f0" and the type of "f 0"?
Thanks a lot in advance for any suggestions
It has nothing to do with your particular definitions: if you do it (as you should!) with the standard implementation, the same thing happens.
Prelude> let f0 = maximum
Prelude> :t f0
f0 :: [()] -> ()
Anyway, first you should give f
a signature.
f :: Ord a => Int -> [a] -> a
If you do that for f0
as well, all will work fine:
f0 :: Ord a => [a] -> a
Now the question is, why would ghci deduce such a stupid signature? It's the Dreaded Monomorphism Restriction's fault. That means, whenever you define something "as a constant(-applicative form)", i.e. a simple equation
c = any odd stuff
then the compiler refuses to give that automatically a polymorphic signature (like, with a
type variables in it). Instead, it defaults to the "simplest usable" type, which for an Ord
constraint unfortunately is the completely useless ()
.
You can turn the monomorphism restriction off, then it'll work even without a signature:
Prelude> :set -XNoMonomorphismRestriction
Prelude> let f0 = maximum
Prelude> :t f0
f0 :: Ord a => [a] -> a
But honestly, on the top level you should always use manual signatures anyway.