Suppose we have the following newtype
definition:
newtype A = A { _run :: Monad m => A -> [Int] -> m Int }
This does not compile with GHC 8.0.2:
error: Not in scope: type variable ‘m’
Replacing m
with a concrete typeclass like IO
or []
does compile, as I would expect. Given that this is ok, why does GHC not allow the signature above? What is wrong with adding a typeclass constraint inside of this newtype
?
It depends on what you're trying to store in
A
.If you're trying to store any function like that, as long as
m
is aMonad
, use it as a type parameter, and specify this contraint in your functions:You could then have things like
A [] -> [Int] -> [Int]
orA Maybe -> [Int] -> Maybe Int
inside the constructor.On the other hand, if you want to force the data you store to be polymorphic, you can use the GHC extension
RankNTypes
.You couldn't have things like
A -> [Int] -> [Int]
orA -> [Int] -> Maybe Int
within the constructor, because theforall
forces them to be general over anyMonad m
, so it would have to be of typeMonad m => A -> [Int] -> Maybe Int
.This will only really be useful if you intend to use different specific
Monad
instances for anA
-value. For example, Lenses work this way by using different functors to do different things to the lens.This is possible:
It's hard to tell what you want to do, but this isn't very usable. Any value of type
A
needs to work for all monads (you don't get to choose).This is also possible, with the same restrictions:
But perhaps you mean something more like
This allows for values of different types of
A
using different monads.How would GHC know what instance of
Monad
to use when you create a piece of data of typeA
?Or, put another way, the type variable
m
isn't in scope on the left hand side of the type definition. That means it doesn't know whatm
should be, and can't work it out. It's implicit.I'm sure there's some way you could do what you want to with an extension, probably using an explicit forall. (The RankNTypes extension), however we'd need to know what you were after a bit more.