问题
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?
回答1:
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.
来源:https://stackoverflow.com/questions/65362659/how-to-compose-polymorphic-functions-in-haskell