0

I have the following file:

module SimpleComposition where

class Domain a where
    f :: a -> a
    g :: a -> a

h = f . g

When trying to loading it in ghci, I get the error

src\play.hs:7:5: error:
    * No instance for (Domain c0) arising from a use of `f'
    * In the first argument of `(.)', namely `f'
      In the expression: f . g
      In an equation for `h': h = f . g

I believe the problem is that the type of both f and g is forall a. Domain a => a ->a and not simply a -> a, so these foralls are in the way. But I still want to compose them. How?

leftaroundabout
  • 117,950
  • 5
  • 174
  • 319
Seno
  • 157
  • 8

1 Answers1

5

This is the monomorphism restriction's fault. Because you wrote h = ... as a constant applicative form, the compiler refuses to infer a polymorphic form for it and instead looks for some way to default it to a concrete type – but there is no information available to do that.

It does compile if you add

{-# LANGUAGE NoMonomorphismRestriction #-}

to the top of the file. But a better idea is to just write the signature explicitly yourself:

h :: Domain a => a -> a
h = f . g

That compiles with the monomorphism restriction either enabled or disabled.

Note that within GHCi it is disabled by default, but that only comes into action after the module has been loaded. In a module you're only loading, it still applies.

leftaroundabout
  • 117,950
  • 5
  • 174
  • 319
  • I changed the question while you were answering because I noticed the solution of putting a signature myself. I am still trying to make it work though. – Seno Dec 18 '20 at 19:39
  • Yeah, don't do that. The edited question is about a different issue, so just ask it as a separate question. – leftaroundabout Dec 18 '20 at 20:07
  • It is the same issue, but closer to my actual problem and avoiding the obvious solution that I cannot use in the code I am writing. But sorry, I am a noob. – Seno Dec 18 '20 at 20:25
  • 1
    No, that's fine, both your question as you originally asked it and the one from the edit are worthwhile questions. Just, again, they're actually quite different problems under the hood, therefore they should be asked as two separate questions. – leftaroundabout Dec 18 '20 at 21:22