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.