about summary refs log tree commit diff
path: root/third_party/bazel/rules_haskell/examples/transformers/Control/Monad/Trans/Class.hs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/bazel/rules_haskell/examples/transformers/Control/Monad/Trans/Class.hs')
-rw-r--r--third_party/bazel/rules_haskell/examples/transformers/Control/Monad/Trans/Class.hs262
1 files changed, 0 insertions, 262 deletions
diff --git a/third_party/bazel/rules_haskell/examples/transformers/Control/Monad/Trans/Class.hs b/third_party/bazel/rules_haskell/examples/transformers/Control/Monad/Trans/Class.hs
deleted file mode 100644
index b92bc0e8b0..0000000000
--- a/third_party/bazel/rules_haskell/examples/transformers/Control/Monad/Trans/Class.hs
+++ /dev/null
@@ -1,262 +0,0 @@
-{-# LANGUAGE CPP #-}
-#if __GLASGOW_HASKELL__ >= 702
-{-# LANGUAGE Safe #-}
-#endif
-#if __GLASGOW_HASKELL__ >= 710
-{-# LANGUAGE AutoDeriveTypeable #-}
-#endif
------------------------------------------------------------------------------
--- |
--- Module      :  Control.Monad.Trans.Class
--- Copyright   :  (c) Andy Gill 2001,
---                (c) Oregon Graduate Institute of Science and Technology, 2001
--- License     :  BSD-style (see the file LICENSE)
---
--- Maintainer  :  R.Paterson@city.ac.uk
--- Stability   :  experimental
--- Portability :  portable
---
--- The class of monad transformers.
---
--- A monad transformer makes a new monad out of an existing monad, such
--- that computations of the old monad may be embedded in the new one.
--- To construct a monad with a desired set of features, one typically
--- starts with a base monad, such as 'Data.Functor.Identity.Identity', @[]@ or 'IO', and
--- applies a sequence of monad transformers.
------------------------------------------------------------------------------
-
-module Control.Monad.Trans.Class (
-    -- * Transformer class
-    MonadTrans(..)
-
-    -- * Conventions
-    -- $conventions
-
-    -- * Strict monads
-    -- $strict
-
-    -- * Examples
-    -- ** Parsing
-    -- $example1
-
-    -- ** Parsing and counting
-    -- $example2
-
-    -- ** Interpreter monad
-    -- $example3
-  ) where
-
--- | The class of monad transformers.  Instances should satisfy the
--- following laws, which state that 'lift' is a monad transformation:
---
--- * @'lift' . 'return' = 'return'@
---
--- * @'lift' (m >>= f) = 'lift' m >>= ('lift' . f)@
-
-class MonadTrans t where
-    -- | Lift a computation from the argument monad to the constructed monad.
-    lift :: (Monad m) => m a -> t m a
-
-{- $conventions
-Most monad transformer modules include the special case of applying
-the transformer to 'Data.Functor.Identity.Identity'.  For example,
-@'Control.Monad.Trans.State.Lazy.State' s@ is an abbreviation for
-@'Control.Monad.Trans.State.Lazy.StateT' s 'Data.Functor.Identity.Identity'@.
-
-Each monad transformer also comes with an operation @run@/XXX/@T@ to
-unwrap the transformer, exposing a computation of the inner monad.
-(Currently these functions are defined as field labels, but in the next
-major release they will be separate functions.)
-
-All of the monad transformers except 'Control.Monad.Trans.Cont.ContT'
-and 'Control.Monad.Trans.Cont.SelectT' are functors on the category
-of monads: in addition to defining a mapping of monads, they
-also define a mapping from transformations between base monads to
-transformations between transformed monads, called @map@/XXX/@T@.
-Thus given a monad transformation @t :: M a -> N a@, the combinator
-'Control.Monad.Trans.State.Lazy.mapStateT' constructs a monad
-transformation
-
-> mapStateT t :: StateT s M a -> StateT s N a
-
-For these monad transformers, 'lift' is a natural transformation in the
-category of monads, i.e. for any monad transformation @t :: M a -> N a@,
-
-* @map@/XXX/@T t . 'lift' = 'lift' . t@
-
-Each of the monad transformers introduces relevant operations.
-In a sequence of monad transformers, most of these operations.can be
-lifted through other transformers using 'lift' or the @map@/XXX/@T@
-combinator, but a few with more complex type signatures require
-specialized lifting combinators, called @lift@/Op/
-(see "Control.Monad.Signatures").
--}
-
-{- $strict
-
-A monad is said to be /strict/ if its '>>=' operation is strict in its first
-argument.  The base monads 'Maybe', @[]@ and 'IO' are strict:
-
->>> undefined >> return 2 :: Maybe Integer
-*** Exception: Prelude.undefined
-
-However the monad 'Data.Functor.Identity.Identity' is not:
-
->>> runIdentity (undefined >> return 2)
-2
-
-In a strict monad you know when each action is executed, but the monad
-is not necessarily strict in the return value, or in other components
-of the monad, such as a state.  However you can use 'seq' to create
-an action that is strict in the component you want evaluated.
--}
-
-{- $example1
-
-The first example is a parser monad in the style of
-
-* \"Monadic parsing in Haskell\", by Graham Hutton and Erik Meijer,
-/Journal of Functional Programming/ 8(4):437-444, July 1998
-(<http://www.cs.nott.ac.uk/~pszgmh/bib.html#pearl>).
-
-We can define such a parser monad by adding a state (the 'String' remaining
-to be parsed) to the @[]@ monad, which provides non-determinism:
-
-> import Control.Monad.Trans.State
->
-> type Parser = StateT String []
-
-Then @Parser@ is an instance of @MonadPlus@: monadic sequencing implements
-concatenation of parsers, while @mplus@ provides choice.  To use parsers,
-we need a primitive to run a constructed parser on an input string:
-
-> runParser :: Parser a -> String -> [a]
-> runParser p s = [x | (x, "") <- runStateT p s]
-
-Finally, we need a primitive parser that matches a single character,
-from which arbitrarily complex parsers may be constructed:
-
-> item :: Parser Char
-> item = do
->     c:cs <- get
->     put cs
->     return c
-
-In this example we use the operations @get@ and @put@ from
-"Control.Monad.Trans.State", which are defined only for monads that are
-applications of 'Control.Monad.Trans.State.Lazy.StateT'.  Alternatively one
-could use monad classes from the @mtl@ package or similar, which contain
-methods @get@ and @put@ with types generalized over all suitable monads.
--}
-
-{- $example2
-
-We can define a parser that also counts by adding a
-'Control.Monad.Trans.Writer.Lazy.WriterT' transformer:
-
-> import Control.Monad.Trans.Class
-> import Control.Monad.Trans.State
-> import Control.Monad.Trans.Writer
-> import Data.Monoid
->
-> type Parser = WriterT (Sum Int) (StateT String [])
-
-The function that applies a parser must now unwrap each of the monad
-transformers in turn:
-
-> runParser :: Parser a -> String -> [(a, Int)]
-> runParser p s = [(x, n) | ((x, Sum n), "") <- runStateT (runWriterT p) s]
-
-To define the @item@ parser, we need to lift the
-'Control.Monad.Trans.State.Lazy.StateT' operations through the
-'Control.Monad.Trans.Writer.Lazy.WriterT' transformer.
-
-> item :: Parser Char
-> item = do
->     c:cs <- lift get
->     lift (put cs)
->     return c
-
-In this case, we were able to do this with 'lift', but operations with
-more complex types require special lifting functions, which are provided
-by monad transformers for which they can be implemented.  If you use the
-monad classes of the @mtl@ package or similar, this lifting is handled
-automatically by the instances of the classes, and you need only use
-the generalized methods @get@ and @put@.
-
-We can also define a primitive using the Writer:
-
-> tick :: Parser ()
-> tick = tell (Sum 1)
-
-Then the parser will keep track of how many @tick@s it executes.
--}
-
-{- $example3
-
-This example is a cut-down version of the one in
-
-* \"Monad Transformers and Modular Interpreters\",
-by Sheng Liang, Paul Hudak and Mark Jones in /POPL'95/
-(<http://web.cecs.pdx.edu/~mpj/pubs/modinterp.html>).
-
-Suppose we want to define an interpreter that can do I\/O and has
-exceptions, an environment and a modifiable store.  We can define
-a monad that supports all these things as a stack of monad transformers:
-
-> import Control.Monad.Trans.Class
-> import Control.Monad.Trans.State
-> import qualified Control.Monad.Trans.Reader as R
-> import qualified Control.Monad.Trans.Except as E
-> import Control.Monad.IO.Class
->
-> type InterpM = StateT Store (R.ReaderT Env (E.ExceptT Err IO))
-
-for suitable types @Store@, @Env@ and @Err@.
-
-Now we would like to be able to use the operations associated with each
-of those monad transformers on @InterpM@ actions.  Since the uppermost
-monad transformer of @InterpM@ is 'Control.Monad.Trans.State.Lazy.StateT',
-it already has the state operations @get@ and @set@.
-
-The first of the 'Control.Monad.Trans.Reader.ReaderT' operations,
-'Control.Monad.Trans.Reader.ask', is a simple action, so we can lift it
-through 'Control.Monad.Trans.State.Lazy.StateT' to @InterpM@ using 'lift':
-
-> ask :: InterpM Env
-> ask = lift R.ask
-
-The other 'Control.Monad.Trans.Reader.ReaderT' operation,
-'Control.Monad.Trans.Reader.local', has a suitable type for lifting
-using 'Control.Monad.Trans.State.Lazy.mapStateT':
-
-> local :: (Env -> Env) -> InterpM a -> InterpM a
-> local f = mapStateT (R.local f)
-
-We also wish to lift the operations of 'Control.Monad.Trans.Except.ExceptT'
-through both 'Control.Monad.Trans.Reader.ReaderT' and
-'Control.Monad.Trans.State.Lazy.StateT'.  For the operation
-'Control.Monad.Trans.Except.throwE', we know @throwE e@ is a simple
-action, so we can lift it through the two monad transformers to @InterpM@
-with two 'lift's:
-
-> throwE :: Err -> InterpM a
-> throwE e = lift (lift (E.throwE e))
-
-The 'Control.Monad.Trans.Except.catchE' operation has a more
-complex type, so we need to use the special-purpose lifting function
-@liftCatch@ provided by most monad transformers.  Here we use
-the 'Control.Monad.Trans.Reader.ReaderT' version followed by the
-'Control.Monad.Trans.State.Lazy.StateT' version:
-
-> catchE :: InterpM a -> (Err -> InterpM a) -> InterpM a
-> catchE = liftCatch (R.liftCatch E.catchE)
-
-We could lift 'IO' actions to @InterpM@ using three 'lift's, but @InterpM@
-is automatically an instance of 'Control.Monad.IO.Class.MonadIO',
-so we can use 'Control.Monad.IO.Class.liftIO' instead:
-
-> putStr :: String -> InterpM ()
-> putStr s = liftIO (Prelude.putStr s)
-
--}