4

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 
ftl
  • 647
  • 3
  • 13
  • 4
    `p f :: (C a) => a -> a` is the proper response to `:t p f`, but you entered `p f`. – Reid Barton Jul 23 '15 at 16:41
  • The question that GHCi is asking is, *"I know it's an instance of `C`, but which instance is it? Otherwise, I can't determine if I can `show` it or not."* – AJF Jul 23 '15 at 21:20

2 Answers2

8

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'
Cirdec
  • 24,019
  • 2
  • 50
  • 100
4

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 
András Kovács
  • 29,931
  • 3
  • 53
  • 99
  • 3
    Even disabling the monomorphism restriction with `:set -XNoMonomorphismRestriction` entering the naked expression `p f` into ghci results in the error `No instance for (C c0) ...`. – Cirdec Jul 23 '15 at 15:01
  • 1
    I think that's an artifact arising from GHCi-7.8 trying to print it. GHCi-7.10 doesn't give that error message at all (instead it throws `No instance for Show...`). – András Kovács Jul 23 '15 at 15:07
  • 8
    It doesn't have anything to do with printing (``p f `seq` ()`` also gives an error), and it's not really the MR either. It's something much more basic: GHC cannot *evaluate* a value with a type class context without choosing a dictionary to pass in. In particular, no matter how you slice it, it doesn't know *which* type's `foo` to use here. – Ørjan Johansen Jul 23 '15 at 15:39