Reputation: 647
Given the following code:
class C a where
foo :: a -> a
f :: (C a) => a -> a
f = id
p :: (C a) => (a -> a) -> a -> a
p g = foo . g
Now, if I try to invoke p f, GHC complains:
> p f
No instance for (C a0) arising from a use of `p'
In the expression: p f
In an equation for `it': it = p f
I find that somewhat surprising, since f only accepts an "a" which has to be an instance of the typeclass C. What is the reason?
Edit: I know I did not define any instance for C but shouldn't the "proper" response be:
p f :: (C a) => a -> a
Upvotes: 4
Views: 100
Reputation: 24156
When you put a plain expression into ghci, it is basically trying to print
it, so
> p f
is approximately the same as having the following in a file
main :: IO ()
main = print $ p f
As you pointed out, p f :: (C a) => a -> a
. In order to print $ p f
GHC needs to evaluate p f
. GHC cannot evaluate a value with a type class context without choosing a dictionary to pass in. To do so, it needs to find a C a
instance for all a
, which doesn't exit. It also needs to find a Show
instance for a -> a
. The inability to find either of these results in two errors
No instance for (Show (a -> a)) arising from a use of `print'
No instance for (C a) arising from a use of `p'
Upvotes: 8
Reputation: 30103
It's the dreaded monomorphism restriction in action. By default, GHC doesn't allow us to have top-level value definitions without type annotations if the inferred type has a class constraint. You can remedy the situation by
a.) Turning the restriction off by adding {-# LANGUAGE NoMonomorphismRestriction #-}
to the top of your source.
b.) Adding type annotations to affected top-level bindings:
foo :: C a => a -> a
foo = p f
c.) Expanding function definitions (if possible):
foo x = p f x
Upvotes: 4