I'm writing the Monad instance for this type using ReaderT and deriving via
newtype HIO a = HIO {runHIO :: Set HiPermission -> IO a}
I've tried to do it this way
newtype HIO a = HIO {runHIO :: Set HiPermission -> IO a}
deriving (Functor, Applicative, Monad) via (ReaderT (Set HiPermission) IO)
but got error:
Couldn't match representation of type `Set HiPermission -> IO c' with that of `ReaderT (Set HiPermission) IO c'
arising from the coercion of the method
What am I doing wrong?
A likely cause of the problem is that you are importing the
ReaderTtype, but not theReaderTvalue constructor, that is, the function of type(r -> m a) -> ReaderT r m athat builds values of typeReaderT.For example, you might have written
instead of
or
But, why is it necessary for the
ReaderTvalue constructor to be in scope?The reason is that
DerivingViarelies onData.Coerceunder the hood. In the module which defines the instance, we must be able to coerce to the "via" type, in this caseReaderT (Set HiPermission) IO.And, as it turns out, to be able to wrap/unwrap a newtype like
ReaderTusing coercions, we need to have its value constructor in scope. Quoting from the coerce Haddocks: