error-continuations-0.1.0.0: src/Control/Monad/MaybeCont.hs
{-|
Module : Control.Monad.MaybeContT
Description : The 'MaybeCont' type and API
Copyright : (c) Eitan Chatav, 2015
License : PublicDomain
Maintainer : eitan.chatav@gmail.com
Stability : experimental
The 'MaybeCont' type and API provide an idiomatic way to handle possibly
failing computations in continuation passing style.
-}
module Control.Monad.MaybeCont
( MaybeCont
, MaybeContT()
, maybeCont
, runMaybeCont
, liftMaybe
, nothingC
, mapMaybeCont
, withMaybeContJust
, withMaybeContNothing
) where
import Control.Monad.Trans.MaybeCont
import Data.Functor.Identity
-- |'MaybeCont' 'a' 'r' is a CPS computation that produces an intermediate
-- result of type 'a' within a CPS computation which produces either a just
-- or nothing.
type MaybeCont a r = MaybeContT a Identity r
-- |Construct a continuation-passing computation from a function.
maybeCont :: (a -> (r -> a) -> a) -> MaybeCont a r
maybeCont mc = MaybeContT $ \ma k -> Identity $
mc (runIdentity ma) (runIdentity . k)
-- |The result of running a CPS computation with given nothing and just
-- continuations.
--
-- prop> runMaybeCont . maybeCont = id
-- prop> maybeCont . runMaybeCont = id
runMaybeCont :: MaybeCont a r -> (a -> (r -> a) -> a)
runMaybeCont mc a k = runIdentity $
runMaybeContT mc (Identity a) (Identity . k)
-- |'liftMaybe' embeds 'Maybe' in 'MaybeCont' 'a'.
liftMaybe :: Maybe r -> MaybeCont a r
liftMaybe may = maybeCont $ \a k -> maybe a k may
-- |Apply a function to transform the result of a continuation-passing
-- computation.
mapMaybeCont :: (a -> a) -> MaybeCont a r -> MaybeCont a r
mapMaybeCont = mapMaybeContT . fmap
-- |Apply a function to transform the just continuation passed to a
-- continuation-passing computation.
withMaybeContJust :: ((r' -> a) -> r -> a)
-> MaybeCont a r
-> MaybeCont a r'
withMaybeContJust f = withMaybeContTJust ((Identity .) . f . (runIdentity .))
-- |Apply a function to transform the nothing continuation passed to an
-- continuation-passing computation.
withMaybeContNothing :: (a -> a) -> MaybeCont a r -> MaybeCont a r
withMaybeContNothing = withMaybeContTNothing . fmap