Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typeclasses 101: GHC too "eager" to derive instance?

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 
like image 853
ftl Avatar asked Dec 15 '22 13:12

ftl


1 Answers

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'
like image 98
Cirdec Avatar answered Dec 23 '22 07:12

Cirdec