문제

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top