I have to be shouted that this 'hoist' on Free Monad is impossible?

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?

Have you tried liftF?

You might want to use them

transFreeT :: (Monad m, Functor g) => (forall a. f a -> g a) -> FreeT f m b -> FreeT g m b
liftF :: (Functor f, MonadFree f m) => f a -> m a

Note that specializing m to FreeT f n in liftF, you have

liftF :: (Functor f, Monad n) => f a -> FreeT f n a
1 Like