Skip to content

Instantly share code, notes, and snippets.

@louispan
Created March 7, 2018 20:31
Show Gist options
  • Save louispan/1c7792d45ebe5559ffc45aa9db461c35 to your computer and use it in GitHub Desktop.
Save louispan/1c7792d45ebe5559ffc45aa9db461c35 to your computer and use it in GitHub Desktop.
Combine reading and producing monads
import Control.Monad.Morph
import Data.Functor.Identity
-- | This function combines two different monadic effects,
-- where one of the effects is a reader effect and the other is a
-- producing effect.
--
-- This version results in the reader monad's inner effect to be wrapped
-- around the producing effect.
-- This requires the Reader inner effect to be an MFunctor on Identity.
--
-- This can enable past-Dependence.
-- Elm has foldp : (a -> state -> state) -> state -> Signal a -> Signal state
-- This is equivalent to a creating a @StateT state (Signal m) ()@
--
-- This function is a more general form of @StateT state (Signal m) ()@ where
-- given a reader monad to transform "a" to "c" with effects, and an "as"
-- monad that produces "a"s with other effects, run the result of "as" through
-- the reader monad to produce "c"s with both effects.
-- @
-- hoistedBind :: Monad m => m a -> (a -> (State s) c) -> StateT s m c
-- hoistedBind :: Signal STM a -> (a -> (State s) c) -> StateT state (Signal STM) c
-- hoistedBind :: Pipes.Concurrent.Input a -> (a -> (State s) c) -> StateT state Pipes.Concurrent.Input c
-- @
hoistedBind :: (Monad m, Monad (t m), MonadTrans t, MFunctor t)
=> m a -> (a -> (t Identity) c) -> t m c
hoistedBind as f = lift as >>= (hoist generalize . f)
-- | An alternate form of runReaderM where the producing effect is
-- wrapped around the reader monad's inner effect.
-- This requires the producing effect to be an MFunctor on Identity.
hoistedBind' :: (Monad m, Monad (t m), MonadTrans t, MFunctor t)
=> (t Identity) a -> (a -> m c) -> t m c
hoistedBind' as f = hoist generalize as >>= (lift . f)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment