I have this record:
import Data.Functor.Identity
import Control.Monad.Trans.Identity
import Data.Coerce
data Env m = Env {
logger :: String -> m ()
}
env :: Env IO
env = undefined
and this coercion function
decorate
:: Coercible (r_ m) (r_ (IdentityT m))
=> r_ m -> r_ (IdentityT m)
decorate = coerce
which is applicable to the record value without problems:
decoratedEnv :: Env (IdentityT IO)
decoratedEnv = decorate env
However, if I define the only slightly more complex record
data Env' h m = Env' {
logger' :: h (String -> m ())
}
env' :: Env' Identity IO
env' = undefined
And try to insert an IdentityT wrapper like I did before
decoratedEnv' :: Env' Identity (IdentityT IO)
decoratedEnv' = decorate env'
I get the error:
* Couldn't match type `IO' with `IdentityT IO'
arising from a use of `decorate'
To my mind, the extra Identity parameter taken by Env' shouldn't stop coerce from working. Why does coerce fail in this case? Is there a way to make coerce work?