Copyright | (C) 2024 Eitan Chatav |
---|---|
License | BSD 3-Clause License (see the file LICENSE) |
Maintainer | Eitan Chatav <eitan.chatav@gmail.com> |
Safe Haskell | Safe-Inferred |
Language | Haskell2010 |
The free indexed monad transformer.
Synopsis
- class (forall f. IxFunctor f => IxMonadTrans (freeIx f), forall f m i j. (IxFunctor f, Monad m, i ~ j) => MonadFree (f i j) (freeIx f i j m)) => IxMonadTransFree freeIx where
- liftFreeIx :: (IxFunctor f, Monad m) => f i j x -> freeIx f i j m x
- hoistFreeIx :: (IxFunctor f, IxFunctor g, Monad m) => (forall i j x. f i j x -> g i j x) -> freeIx f i j m x -> freeIx g i j m x
- foldFreeIx :: (IxFunctor f, IxMonadTrans t, Monad m) => (forall i j x. f i j x -> t i j m x) -> freeIx f i j m x -> t i j m x
- coerceFreeIx :: (IxMonadTransFree freeIx0, IxMonadTransFree freeIx1, IxFunctor f, Monad m) => freeIx0 f i j m x -> freeIx1 f i j m x
- type IxFunctor f = forall i j. Functor (f i j)
- data IxMap f i j x where
- liftFreerIx :: (IxMonadTransFree freeIx, Monad m) => f i j x -> freeIx (IxMap f) i j m x
- hoistFreerIx :: (IxMonadTransFree freeIx, Monad m) => (forall i j x. f i j x -> g i j x) -> freeIx (IxMap f) i j m x -> freeIx (IxMap g) i j m x
- foldFreerIx :: (IxMonadTransFree freeIx, IxMonadTrans t, Monad m) => (forall i j x. f i j x -> t i j m x) -> freeIx (IxMap f) i j m x -> t i j m x
Documentation
class (forall f. IxFunctor f => IxMonadTrans (freeIx f), forall f m i j. (IxFunctor f, Monad m, i ~ j) => MonadFree (f i j) (freeIx f i j m)) => IxMonadTransFree freeIx where Source #
The free IxMonadTrans
generated by an IxFunctor
is characterized by the IxMonadTransFree
class
up to the isomorphism coerceFreeIx
.
IxMonadTransFree
and IxMap
, the free IxMonadTrans
and
the free IxFunctor
, can be combined as a "freer" IxMonadTrans
and used as a DSL generated by primitive commands like this
Conor McBride example.
>>>
:set -XGADTs -XDataKinds
>>>
import Data.Kind
>>>
type DVD = String
>>>
:{
data DVDCommand :: Bool -- ^ drive is full before command -> Bool -- ^ drive is full after command -> Type -- ^ return type -> Type where Insert :: DVD -> DVDCommand 'False 'True () Eject :: DVDCommand 'True 'False DVD :}
>>>
:{
insert :: (IxMonadTransFree freeIx, Monad m) => DVD -> freeIx (IxMap DVDCommand) 'False 'True m () insert dvd = liftFreerIx (Insert dvd) :}
>>>
:{
eject :: (IxMonadTransFree freeIx, Monad m) => freeIx (IxMap DVDCommand) 'True 'False m DVD eject = liftFreerIx Eject :}
>>>
:set -XQualifiedDo
>>>
import qualified Control.Monad.Trans.Indexed.Do as Indexed
>>>
:{
swap :: (IxMonadTransFree freeIx, Monad m) => DVD -> freeIx (IxMap DVDCommand) 'True 'True m DVD swap dvd = Indexed.do dvd' <- eject insert dvd return dvd' :}
>>>
import Control.Monad.Trans
>>>
:{
printDVD :: IxMonadTransFree freeIx => freeIx (IxMap DVDCommand) 'True 'True IO () printDVD = Indexed.do dvd <- eject insert dvd lift $ putStrLn dvd :}
liftFreeIx :: (IxFunctor f, Monad m) => f i j x -> freeIx f i j m x Source #
hoistFreeIx :: (IxFunctor f, IxFunctor g, Monad m) => (forall i j x. f i j x -> g i j x) -> freeIx f i j m x -> freeIx g i j m x Source #
foldFreeIx :: (IxFunctor f, IxMonadTrans t, Monad m) => (forall i j x. f i j x -> t i j m x) -> freeIx f i j m x -> t i j m x Source #
Instances
IxMonadTransFree (FreeIx :: (k -> k -> Type -> Type) -> k -> k -> (Type -> Type) -> Type -> Type) Source # | |
Defined in Control.Monad.Trans.Indexed.Free.Fold liftFreeIx :: forall f (m :: Type -> Type) (i :: k0) (j :: k0) x. (IxFunctor f, Monad m) => f i j x -> FreeIx f i j m x Source # hoistFreeIx :: forall f g (m :: Type -> Type) (i :: k0) (j :: k0) x. (IxFunctor f, IxFunctor g, Monad m) => (forall (i1 :: k0) (j1 :: k0) x1. f i1 j1 x1 -> g i1 j1 x1) -> FreeIx f i j m x -> FreeIx g i j m x Source # foldFreeIx :: forall f t (m :: Type -> Type) (i :: k0) (j :: k0) x. (IxFunctor f, IxMonadTrans t, Monad m) => (forall (i1 :: k0) (j1 :: k0) x1. f i1 j1 x1 -> t i1 j1 m x1) -> FreeIx f i j m x -> t i j m x Source # | |
IxMonadTransFree (FreeIx :: (k -> k -> Type -> Type) -> k -> k -> (Type -> Type) -> Type -> Type) Source # | |
Defined in Control.Monad.Trans.Indexed.Free.Wrap liftFreeIx :: forall f (m :: Type -> Type) (i :: k0) (j :: k0) x. (IxFunctor f, Monad m) => f i j x -> FreeIx f i j m x Source # hoistFreeIx :: forall f g (m :: Type -> Type) (i :: k0) (j :: k0) x. (IxFunctor f, IxFunctor g, Monad m) => (forall (i1 :: k0) (j1 :: k0) x1. f i1 j1 x1 -> g i1 j1 x1) -> FreeIx f i j m x -> FreeIx g i j m x Source # foldFreeIx :: forall f t (m :: Type -> Type) (i :: k0) (j :: k0) x. (IxFunctor f, IxMonadTrans t, Monad m) => (forall (i1 :: k0) (j1 :: k0) x1. f i1 j1 x1 -> t i1 j1 m x1) -> FreeIx f i j m x -> t i j m x Source # |
coerceFreeIx :: (IxMonadTransFree freeIx0, IxMonadTransFree freeIx1, IxFunctor f, Monad m) => freeIx0 f i j m x -> freeIx1 f i j m x Source #
coerceFreeIx = foldFreeIx liftFreeIx
id = coerceFreeIx . coerceFreeIx
data IxMap f i j x where Source #
IxMap
is the free IxFunctor
. It's a left Kan extension.
Combining IxMonadTransFree
with IxMap
as demonstrated in the above example,
gives the "freer" IxMonadTrans
, modeled on this
Oleg Kiselyov explanation.
liftFreerIx :: (IxMonadTransFree freeIx, Monad m) => f i j x -> freeIx (IxMap f) i j m x Source #
hoistFreerIx :: (IxMonadTransFree freeIx, Monad m) => (forall i j x. f i j x -> g i j x) -> freeIx (IxMap f) i j m x -> freeIx (IxMap g) i j m x Source #
foldFreerIx :: (IxMonadTransFree freeIx, IxMonadTrans t, Monad m) => (forall i j x. f i j x -> t i j m x) -> freeIx (IxMap f) i j m x -> t i j m x Source #