I am trying to implement some closed effect with How Free Monads Yield Extensible Effects 's SimplexFX And copying get something like:
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Test where
import Data.Functor.Identity
import Data.Functor.Sum
import Control.Monad (ap, liftM)
import Control.Monad.Trans.Class
data FreeF f a b = Pure a | Free (f b)
newtype FreeT f m a = FreeT { runFreeT :: m (FreeF f a (FreeT f m a)) }
type Free f = FreeT f Identity
instance (Functor f, Functor m) => Functor (FreeT f m) where
fmap f (FreeT m) = FreeT (fmap f' m) where
f' (Pure a) = Pure (f a)
f' (Free as) = Free (fmap (fmap f) as)
instance (Functor f, Monad m) => Applicative (FreeT f m) where
pure a = FreeT (return (Pure a))
{-# INLINE pure #-}
(<*>) = ap
{-# INLINE (<*>) #-}
instance (Functor f, Monad m) => Monad (FreeT f m) where
return = pure
{-# INLINE return #-}
FreeT m >>= f = FreeT $ m >>= \v -> case v of
Pure a -> runFreeT (f a)
Free w -> return (Free (fmap (>>= f) w))
instance Functor f => MonadTrans (FreeT f) where
lift = FreeT . liftM Pure
{-# INLINE lift #-}
Stolen from the free source code (https://hackage.haskell.org/package/free-5.2/docs/src/Control.Monad.Trans.Free.html#Free)
with the added
type SimplestFX f g m = FreeT (Sum f g) m
from the blogpost.
Now I want to make my custom Monad Transformer
data MyMonadT m a = FreeT MyCustomInteriorData m a
deriving (Functor, Applicative, Monad, MonadTrans)
now I want to get some kind of hoist
hoist :: MyMonadT m a -> SimplexFX (Sum (MyMonadT Identity) (g)) m a
Is this even possible?