indexed-transformers-0.1.0.4: Atkey indexed monad transformers
Copyright(C) 2024 Eitan Chatav
LicenseBSD 3-Clause License (see the file LICENSE)
MaintainerEitan Chatav <eitan.chatav@gmail.com>
Safe HaskellSafe-Inferred
LanguageHaskell2010

Control.Monad.Trans.Indexed.Free

Description

The free indexed monad transformer.

Synopsis

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
:}

Methods

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

Instances details
IxMonadTransFree (FreeIx :: (k -> k -> Type -> Type) -> k -> k -> (Type -> Type) -> Type -> Type) Source # 
Instance details

Defined in Control.Monad.Trans.Indexed.Free.Fold

Methods

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 # 
Instance details

Defined in Control.Monad.Trans.Indexed.Free.Wrap

Methods

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

type IxFunctor f = forall i j. Functor (f i j) Source #

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.

Constructors

IxMap :: (x -> y) -> f i j x -> IxMap f i j y 

Instances

Instances details
Functor (IxMap f i j) Source # 
Instance details

Defined in Control.Monad.Trans.Indexed.Free

Methods

fmap :: (a -> b) -> IxMap f i j a -> IxMap f i j b #

(<$) :: a -> IxMap f i j b -> IxMap f i j a #

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 #