In Haskell, how could I embed one free monad in another?

I have two free monads for different operations in different contexts. However, one ( major) DSL must contain another ( action) if a particular operation is in context:

import Control.Monad.Free

data ActionFunctor next = Wait Timeout next
                        | Read URI next

instance Functor ActionFunctor where
  fmap f (Wait timeout next)  = Wait timeout (f next)
  fmap f (Read uri next)      = Read uri (f next)

type Action = Free ActionFunctor


data MajorFunctor next = Log LogText next
                       | Act Action next
                       | Send Message

instance Functor MajorFunctor where
  fmap f (Log text next)    = Log text (f next)
  fmap f (Act action next)  = Act action (f next)
  fmap f (Send message)     = Send message

type Major = Free MajorFunctor

The problem is that the GHC will complain MajorFunctorthat actionin Act Action nextis a kind (* -> *), not just a type. This is due to the fact that in the definition data ActionFunctorit must be taken nextas a type parameter, and in the line Act Actionit does not contain such a parameter. But even the message is clear to me, I'm not sure if I should declare such an additional type parameter in the major-function:

data MajorFunctor actionNext next = ...

, , MajorFunctor MajorFunctor actionNext, . FreeT, , , . action, DSL ​​, bind , , .

+4
2

Act Action a, next a. , , :

{-# LANGUAGE ExistentialQuantification #-}
data MajorFunctor next = Log LogText next
                       | forall a. Act (Action a) (a -> next)
                       | Send Message

instance Functor MajorFunctor where
  fmap f (Log text next)    = Log text (f next)
  fmap f (Act action next)  = Act action (fmap f next)
  fmap f (Send message)     = Send message
+5

, , , next Action.

data MajorFunctor next = Log LogText next
                       | Act (Action next)
                       | Send Message

instance Functor MajorFunctor where
  fmap f (Log text next) = Log text (f next)
  fmap f (Act action) = Act (fmap f action)
  fmap f (Send message) = Send message

: " Action, next", @Cactus : " Action, - ( () ), () next".

co-Yoneda , . , , fmap Action s.

+7

All Articles