Skip to content

Commit

Permalink
freer
Browse files Browse the repository at this point in the history
  • Loading branch information
echatav committed Jan 15, 2024
1 parent c06b83d commit e564c86
Showing 1 changed file with 22 additions and 14 deletions.
36 changes: 22 additions & 14 deletions src/Control/Monad/Trans/Indexed/Free.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

module Control.Monad.Trans.Indexed.Free
( IxFree (ixlift, ixhoist, ixfoldMap), coerceIxFree
, IxFunctor, IxMap (IxMap), hoistIxMap, liftIxMap, lowerIxMap
, IxFunctor, IxMap (IxMap), ixliftFreer, ixhoistFreer
) where

import Control.Monad.Free
Expand All @@ -24,8 +24,9 @@ is characterized by the `IxFree` class
up to the isomorphism `coerceIxFree`.
`IxFree` and `IxMap`, the free `IndexedMonadTrans` and
the free `IxFunctor` can be used as a DSL
generated by primitive commands like [this Conor McBride example]
the free `IxFunctor`, can be combined as a "freer" `IndexedMonadTrans`
and used as a DSL generated by primitive commands like
[this Conor McBride example]
(https://stackoverflow.com/questions/28690448/what-is-indexed-monad).
>>> :set -XGADTs -XDataKinds
Expand All @@ -45,14 +46,14 @@ data DVDCommand
insert
:: (IxFree free, Monad m)
=> DVD -> free (IxMap DVDCommand) 'False 'True m ()
insert dvd = ixlift (liftIxMap (Insert dvd))
insert dvd = ixliftFreer (Insert dvd)
:}
>>> :{
eject
:: (IxFree free, Monad m)
=> free (IxMap DVDCommand) 'True 'False m DVD
eject = ixlift (liftIxMap Eject)
eject = ixliftFreer Eject
:}
>>> :set -XQualifiedDo
Expand Down Expand Up @@ -101,17 +102,24 @@ type IxFunctor
type IxFunctor f = forall i j. Functor (f i j)

{- |
`IxMap` is the free `IxFunctor`. It's a left Kan extension.
Combining `IxFree` with `IxMap` as demonstrated in the above example,
gives the "freer" `IndexedMonadTrans`, modeled on a definition of
[Oleg Kiselyov]
(https://okmij.org/ftp/Computation/free-monad.html#freer)
-}
data IxMap f i j x where
IxMap :: (x -> y) -> f i j x -> IxMap f i j y
instance Functor (IxMap f i j) where
fmap g (IxMap f x) = IxMap (g . f) x
hoistIxMap
:: (forall x. f i j x -> g i j x)
-> IxMap f i j x -> IxMap g i j x
hoistIxMap g (IxMap f x) = IxMap f (g x)
liftIxMap :: g i j x -> IxMap g i j x
liftIxMap = IxMap id
lowerIxMap :: Functor (g i j) => IxMap g i j x -> g i j x
lowerIxMap (IxMap f x) = fmap f x

ixliftFreer
:: (IxFree free, Monad m)
=> f i j x -> free (IxMap f) i j m x
ixliftFreer x = ixlift (IxMap id x)

ixhoistFreer
:: (IxFree free, Monad m)
=> (forall i j x. f i j x -> g i j x)
-> free (IxMap f) i j m x -> free (IxMap g) i j m x
ixhoistFreer f = ixhoist (\(IxMap g x) -> IxMap g (f x))

0 comments on commit e564c86

Please sign in to comment.