about summary refs log tree commit diff
path: root/third_party/bazel/rules_haskell/examples/transformers/Control/Monad/Trans/Cont.hs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/bazel/rules_haskell/examples/transformers/Control/Monad/Trans/Cont.hs')
-rw-r--r--third_party/bazel/rules_haskell/examples/transformers/Control/Monad/Trans/Cont.hs240
1 files changed, 0 insertions, 240 deletions
diff --git a/third_party/bazel/rules_haskell/examples/transformers/Control/Monad/Trans/Cont.hs b/third_party/bazel/rules_haskell/examples/transformers/Control/Monad/Trans/Cont.hs
deleted file mode 100644
index ce2005d4b2..0000000000
--- a/third_party/bazel/rules_haskell/examples/transformers/Control/Monad/Trans/Cont.hs
+++ /dev/null
@@ -1,240 +0,0 @@
-{-# LANGUAGE CPP #-}
-#if __GLASGOW_HASKELL__ >= 702
-{-# LANGUAGE Safe #-}
-#endif
-#if __GLASGOW_HASKELL__ >= 706
-{-# LANGUAGE PolyKinds #-}
-#endif
-#if __GLASGOW_HASKELL__ >= 710
-{-# LANGUAGE AutoDeriveTypeable #-}
-#endif
------------------------------------------------------------------------------
--- |
--- Module      :  Control.Monad.Trans.Cont
--- Copyright   :  (c) The University of Glasgow 2001
--- License     :  BSD-style (see the file LICENSE)
---
--- Maintainer  :  R.Paterson@city.ac.uk
--- Stability   :  experimental
--- Portability :  portable
---
--- Continuation monads.
---
--- Delimited continuation operators are taken from Kenichi Asai and Oleg
--- Kiselyov's tutorial at CW 2011, \"Introduction to programming with
--- shift and reset\" (<http://okmij.org/ftp/continuations/#tutorial>).
---
------------------------------------------------------------------------------
-
-module Control.Monad.Trans.Cont (
-    -- * The Cont monad
-    Cont,
-    cont,
-    runCont,
-    evalCont,
-    mapCont,
-    withCont,
-    -- ** Delimited continuations
-    reset, shift,
-    -- * The ContT monad transformer
-    ContT(..),
-    evalContT,
-    mapContT,
-    withContT,
-    callCC,
-    -- ** Delimited continuations
-    resetT, shiftT,
-    -- * Lifting other operations
-    liftLocal,
-  ) where
-
-import Control.Monad.IO.Class
-import Control.Monad.Trans.Class
-import Data.Functor.Identity
-
-import Control.Applicative
-#if MIN_VERSION_base(4,9,0)
-import qualified Control.Monad.Fail as Fail
-#endif
-
-{- |
-Continuation monad.
-@Cont r a@ is a CPS ("continuation-passing style") computation that produces an
-intermediate result of type @a@ within a CPS computation whose final result type
-is @r@.
-
-The @return@ function simply creates a continuation which passes the value on.
-
-The @>>=@ operator adds the bound function into the continuation chain.
--}
-type Cont r = ContT r Identity
-
--- | Construct a continuation-passing computation from a function.
--- (The inverse of 'runCont')
-cont :: ((a -> r) -> r) -> Cont r a
-cont f = ContT (\ c -> Identity (f (runIdentity . c)))
-{-# INLINE cont #-}
-
--- | The result of running a CPS computation with a given final continuation.
--- (The inverse of 'cont')
-runCont
-    :: Cont r a         -- ^ continuation computation (@Cont@).
-    -> (a -> r)         -- ^ the final continuation, which produces
-                        -- the final result (often 'id').
-    -> r
-runCont m k = runIdentity (runContT m (Identity . k))
-{-# INLINE runCont #-}
-
--- | The result of running a CPS computation with the identity as the
--- final continuation.
---
--- * @'evalCont' ('return' x) = x@
-evalCont :: Cont r r -> r
-evalCont m = runIdentity (evalContT m)
-{-# INLINE evalCont #-}
-
--- | Apply a function to transform the result of a continuation-passing
--- computation.
---
--- * @'runCont' ('mapCont' f m) = f . 'runCont' m@
-mapCont :: (r -> r) -> Cont r a -> Cont r a
-mapCont f = mapContT (Identity . f . runIdentity)
-{-# INLINE mapCont #-}
-
--- | Apply a function to transform the continuation passed to a CPS
--- computation.
---
--- * @'runCont' ('withCont' f m) = 'runCont' m . f@
-withCont :: ((b -> r) -> (a -> r)) -> Cont r a -> Cont r b
-withCont f = withContT ((Identity .) . f . (runIdentity .))
-{-# INLINE withCont #-}
-
--- | @'reset' m@ delimits the continuation of any 'shift' inside @m@.
---
--- * @'reset' ('return' m) = 'return' m@
---
-reset :: Cont r r -> Cont r' r
-reset = resetT
-{-# INLINE reset #-}
-
--- | @'shift' f@ captures the continuation up to the nearest enclosing
--- 'reset' and passes it to @f@:
---
--- * @'reset' ('shift' f >>= k) = 'reset' (f ('evalCont' . k))@
---
-shift :: ((a -> r) -> Cont r r) -> Cont r a
-shift f = shiftT (f . (runIdentity .))
-{-# INLINE shift #-}
-
--- | The continuation monad transformer.
--- Can be used to add continuation handling to any type constructor:
--- the 'Monad' instance and most of the operations do not require @m@
--- to be a monad.
---
--- 'ContT' is not a functor on the category of monads, and many operations
--- cannot be lifted through it.
-newtype ContT r m a = ContT { runContT :: (a -> m r) -> m r }
-
--- | The result of running a CPS computation with 'return' as the
--- final continuation.
---
--- * @'evalContT' ('lift' m) = m@
-evalContT :: (Monad m) => ContT r m r -> m r
-evalContT m = runContT m return
-{-# INLINE evalContT #-}
-
--- | Apply a function to transform the result of a continuation-passing
--- computation.  This has a more restricted type than the @map@ operations
--- for other monad transformers, because 'ContT' does not define a functor
--- in the category of monads.
---
--- * @'runContT' ('mapContT' f m) = f . 'runContT' m@
-mapContT :: (m r -> m r) -> ContT r m a -> ContT r m a
-mapContT f m = ContT $ f . runContT m
-{-# INLINE mapContT #-}
-
--- | Apply a function to transform the continuation passed to a CPS
--- computation.
---
--- * @'runContT' ('withContT' f m) = 'runContT' m . f@
-withContT :: ((b -> m r) -> (a -> m r)) -> ContT r m a -> ContT r m b
-withContT f m = ContT $ runContT m . f
-{-# INLINE withContT #-}
-
-instance Functor (ContT r m) where
-    fmap f m = ContT $ \ c -> runContT m (c . f)
-    {-# INLINE fmap #-}
-
-instance Applicative (ContT r m) where
-    pure x  = ContT ($ x)
-    {-# INLINE pure #-}
-    f <*> v = ContT $ \ c -> runContT f $ \ g -> runContT v (c . g)
-    {-# INLINE (<*>) #-}
-    m *> k = m >>= \_ -> k
-    {-# INLINE (*>) #-}
-
-instance Monad (ContT r m) where
-#if !(MIN_VERSION_base(4,8,0))
-    return x = ContT ($ x)
-    {-# INLINE return #-}
-#endif
-    m >>= k  = ContT $ \ c -> runContT m (\ x -> runContT (k x) c)
-    {-# INLINE (>>=) #-}
-
-#if MIN_VERSION_base(4,9,0)
-instance (Fail.MonadFail m) => Fail.MonadFail (ContT r m) where
-    fail msg = ContT $ \ _ -> Fail.fail msg
-    {-# INLINE fail #-}
-#endif
-
-instance MonadTrans (ContT r) where
-    lift m = ContT (m >>=)
-    {-# INLINE lift #-}
-
-instance (MonadIO m) => MonadIO (ContT r m) where
-    liftIO = lift . liftIO
-    {-# INLINE liftIO #-}
-
--- | @callCC@ (call-with-current-continuation) calls its argument
--- function, passing it the current continuation.  It provides
--- an escape continuation mechanism for use with continuation
--- monads.  Escape continuations one allow to abort the current
--- computation and return a value immediately.  They achieve
--- a similar effect to 'Control.Monad.Trans.Except.throwE'
--- and 'Control.Monad.Trans.Except.catchE' within an
--- 'Control.Monad.Trans.Except.ExceptT' monad.  The advantage of this
--- function over calling 'return' is that it makes the continuation
--- explicit, allowing more flexibility and better control.
---
--- The standard idiom used with @callCC@ is to provide a lambda-expression
--- to name the continuation. Then calling the named continuation anywhere
--- within its scope will escape from the computation, even if it is many
--- layers deep within nested computations.
-callCC :: ((a -> ContT r m b) -> ContT r m a) -> ContT r m a
-callCC f = ContT $ \ c -> runContT (f (\ x -> ContT $ \ _ -> c x)) c
-{-# INLINE callCC #-}
-
--- | @'resetT' m@ delimits the continuation of any 'shiftT' inside @m@.
---
--- * @'resetT' ('lift' m) = 'lift' m@
---
-resetT :: (Monad m) => ContT r m r -> ContT r' m r
-resetT = lift . evalContT
-{-# INLINE resetT #-}
-
--- | @'shiftT' f@ captures the continuation up to the nearest enclosing
--- 'resetT' and passes it to @f@:
---
--- * @'resetT' ('shiftT' f >>= k) = 'resetT' (f ('evalContT' . k))@
---
-shiftT :: (Monad m) => ((a -> m r) -> ContT r m r) -> ContT r m a
-shiftT f = ContT (evalContT . f)
-{-# INLINE shiftT #-}
-
--- | @'liftLocal' ask local@ yields a @local@ function for @'ContT' r m@.
-liftLocal :: (Monad m) => m r' -> ((r' -> r') -> m r -> m r) ->
-    (r' -> r') -> ContT r m a -> ContT r m a
-liftLocal ask local f m = ContT $ \ c -> do
-    r <- ask
-    local f (runContT m (local (const r) . c))
-{-# INLINE liftLocal #-}