I have the type
ActionT TL.Text (ReaderT T.Text IO)
I'm trying to make a MonadReader instance for this so that I do not have to lift ask, but always get
(All instance types must be of the form (T a1 ... an)
where a1 ... an are *distinct type variables*,
and each type variable appears at most once in the instance head.
Use -XFlexibleInstances if you want to disable this)
I've tried a bunch of instance types, a couple below, but they always get the above error
instance MonadReader T.Text (ActionT TL.Text (ReaderT T.Text IO))
instance MonadReader r (ActionT TL.Text (ReaderT r IO))
instance (ScottyError e, MonadReader r m) => MonadReader r (ActionT e (ReaderT r m))
I feel like I'm missing something fundamental with instances. I think I understand FlexibleInstances
but I can't see how that applies here.
Any help with the instance type would be appreciated, I would like to implement ask
and local
myself as the main goal is learning.
Thanks.
I got it working with FlexibleInstances, MultiParamTypeClasses, UndecidableInstances
and
instance (ScottyError e, Monad m, MonadReader r m) => MonadReader r (ActionT e m) where
ask = lift ask
Still working on the implementation of local. I also assume UndecidableInstances
is bad?
I think what I really need is.
instance (ScottyError e, Monad m, MonadReader r m) => MonadReader r (ActionT e (ReaderT r m)) where
But I still cant figure out local
The instance would be
instance (ScottyError e, Monad m, MonadReader r m) => MonadReader r (ActionT e (ReaderT r m)) where
However Scotty does not expose the required functions to implement local.
I am attempting to write a mapActionT
to make it possible to implement local
and I will update this answer if I ever figure out the types to do that :)
Edit:
I think I have mapActionT, but I'm not sure.
mapActionT :: (Monad m, Functor n, ScottyError e) => (forall a . m a -> n a) -> ActionT e m b -> ActionT e n b
mapActionT nat m = ActionT $ flip mapErrorT (runAM m) $ \rt ->
flip mapReaderT rt $ \st ->
StateT $ \s -> fmap (\a -> (a,s)) (nat (evalStateT st s))
I ended up copying the type signature from hoist so that I could bring in Functor n for my fmap.
Any comments on the implementation are welcome.