Control-Monad-MultiPass-0.1.0.0: src/Control/Monad/MultiPass/Utils/UpdateCtx.hs
-- Copyright 2013 Kevin Backhouse.
{-|
Utility functions for working with the 'UpdateThreadContext'
argument of 'createInstrument'. This module is only relevant for
Instrument authoring.
-}
module Control.Monad.MultiPass.Utils.UpdateCtx
( updateCtxFst, updateCtxSnd
, updateCtxLeft, updateCtxRight
)
where
import Control.Exception ( assert )
import Control.Monad.MultiPass
-- | If the thread context is a pair then 'updateCtxFst' creates a new
-- 'UpdateThreadContext' function which can be used to update the
-- first element of the pair.
updateCtxFst
:: UpdateThreadContext rootTC (x,y)
-> UpdateThreadContext rootTC x
updateCtxFst updateCtx f =
do (x,_) <- updateCtx (cross f id)
return x
-- | If the thread context is a pair then 'updateCtxSnd' creates a new
-- 'UpdateThreadContext' function which can be used to update the
-- second element of the pair.
updateCtxSnd
:: UpdateThreadContext rootTC (x,y)
-> UpdateThreadContext rootTC y
updateCtxSnd updateCtx f =
do (_,y) <- updateCtx (cross id f)
return y
cross :: (a -> a') -> (b -> b') -> (a,b) -> (a',b')
cross f g (x,y) = (f x, g y)
-- | If the thread context is an Either of two thread contexts then
-- 'updateCtxLeft' creates a new 'UpdateThreadContext' function which
-- can be used to update the 'Left' element. This function will assert
-- if the thread context is a 'Right' element.
updateCtxLeft
:: UpdateThreadContext rootTC (Either x y)
-> UpdateThreadContext rootTC x
updateCtxLeft updateCtx f =
let g (Left x) = Left (f x)
g (Right _) = assert False $ error "updateCtxLeft"
in
do Left x <- updateCtx g
return x
-- | If the thread context is an Either of two thread contexts then
-- 'updateCtxRight' creates a new 'UpdateThreadContext' function which
-- can be used to update the 'Right' element. This function will assert
-- if the thread context is a 'Left' element.
updateCtxRight
:: UpdateThreadContext rootTC (Either x y)
-> UpdateThreadContext rootTC y
updateCtxRight updateCtx f =
let g (Left _) = assert False $ error "updateCtxRight"
g (Right x) = Right (f x)
in
do Right x <- updateCtx g
return x