Skip to content

Instantly share code, notes, and snippets.

@jdegoes
Created October 27, 2016 20:38
Show Gist options
  • Save jdegoes/dfaa07042f51245fa09716c6387aa5a6 to your computer and use it in GitHub Desktop.
Save jdegoes/dfaa07042f51245fa09716c6387aa5a6 to your computer and use it in GitHub Desktop.
Free applicative in free monad
-- A sequential series of parallel program fragments in `f`:
type SeqPar f a = Free (FreeAp f) a
liftFA :: forall f a. f a -> SeqPar f a
liftFA = pure >>> pure
liftSeq :: forall f a. Free f a -> SeqPar f a
liftSeq fa = foldFree fa liftFA
liftPar :: forall f a. FreeAp f a -> SeqPar f a
liftPar = pure
-- Interprets a parallel fragment `f` into `g`:
type ParInterpreter f g = FreeAp f ~> g
-- Optimizes a parallel fragment `f` into a sequential series of parallel program fragments in `g`:
type ParOptimizer f g = ParInterpreter f (SeqPar g)
-- Applies the most general optimization from a parallel program fragment in `f` to a sequential
-- series of parallel program fragments in `g`:
optimize :: forall f g a. (FreeAp f ~> SeqPar g) -> SeqPar f a -> SeqPar g a
optimize = foldFree
-- Applies a parallel-to-parallel optimization:
parOptimize :: forall f g a. (FreeAp f ~> FreeAp g) -> SeqPar f a -> SeqPar g a
parOoptimize opt = optimize (opt >>> liftPar)
-- Runs a seq/par program by converting each parallel fragment in `f` into an `IO`:
run :: forall f a. (FreeAp f ~> IO) -> SeqPar f a -> IO a
run = foldFree
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment