mtl (Monad Transformer Library)

repository·master·Indexed 19 days ago

https://github.com/haskell/mtl

A collection of monad classes that extend the transformers package, using functional dependencies to provide a generic way to lift monadic actions across different transformer stacks. It includes support for MonadError (ExceptT), MonadReader (ReaderT), MonadState (StateT), and MonadWriter (WriterT).

Tokens
1.5K
Snippets
3
Records
8
Agent score
14%

What's inside mtl

  1. How MTL structure and naming works

    master

    MTL (Monad Transformer Library) extends the transformers package by providing type classes that define monadic operations for various transformers.

    MTL follows a consistent naming convention for a transformer (e.g., Foo):

    1. Module: Control.Monad.Foo contains the interface.
    2. Type Class: MonadFoo defines the operations available within the transformer.
    3. Data Type: FooT is the actual transformer implementation (usually from the transformers package) for which MTL provides instances.
    4. Runner: Functions like runFooT are used to execute the transformed computation.
  2. Migrate to mtl-2.3.x

    master

    In mtl-2.3.x, many re-exports that overlapped with base were removed to achieve PVP compliance and clean up the library design. If your code relies on functions that were previously available via mtl re-exports, you must now import the original modules explicitly.

    Steps to migrate:

    1. Update dependencies: Update your .cabal file to require mtl-2.3.1 or configure your cabal.project to use the specific git tag.
    2. Fix imports: If you encounter compilation errors stating that functions are missing, identify which module they belong to and add an explicit import for that module (e.g., import Control.Monad directly instead of relying on an mtl module to re-export it).
    # Update cabal.project to use mtl-2.3.1 via git
    source-repository-package
      type: git
      location: https://github.com/haskell/mtl
      tag: v2.3.1
    
    allow-newer:
      *:mtl
  3. Lift monadic actions using lift

    master

    When working with monad transformers, you often need to take an action from an inner monad m and wrap it in the transformer t. This is achieved using the lift function from the MonadTrans class in Control.Monad.Trans.Class.

    Signature:

    lift :: (Monad m, MonadTrans t) => m a -> t m a

    Example: Lifting an IO action into an ExceptT transformer:

    data MyError = EmptyLine
    
    mightFail :: ExceptT MyError IO ()
    mightFail = do
      l <- lift getLine
      when (null l) (throwError EmptyLine)
  4. Use Control.Monad.Writer for data accumulation

    master

    The WriterT transformer represents a computation that produces a stream of data (typically a Monoid) in addition to the computed values. This is useful for logging or accumulating values.

    • Class: Control.Monad.Writer.Class.MonadWriter
    • Lazy transformers: Control.Monad.Writer.Lazy.WriterT
    • Strict transformers: Control.Monad.Writer.Strict.WriterT
  5. Use Control.Monad.State for stateful computations

    master

    The StateT transformer represents a computation that can read and write internal state values. If you only need to read values, use Reader instead.

    • Class: Control.Monad.State.Class.MonadState
    • Lazy transformer: Control.Monad.State.Lazy.StateT (default)
    • Strict transformer: Control.Monad.State.Strict.StateT
  6. Use Control.Monad.Reader for environment access

    master

    The ReaderT transformer represents a computation that can read values from a shared environment.

    • Class: Control.Monad.Reader.Class.MonadReader
    • Transformer: Control.Monad.Reader.ReaderT
  7. Use Control.Monad.Except for error handling

    master

    The ExceptT transformer adds the ability to fail with an error in a monadic computation. Use the MonadError class to interact with it. This replaces the deprecated Control.Monad.Error.

    • Class: Control.Monad.Except.Class.MonadError
    • Transformer: Control.Monad.Except.ExceptT
  8. Reference of available Monad Transformers and Classes

    master

    The following table summarizes the primary monad transformers and their associated type classes available in MTL. Note that Control.Monad.Error is deprecated; use Control.Monad.Except instead.

    * Control.Monad.Cont
        - Class: Control.Monad.Cont.Class.MonadCont
        - Transformer: Control.Monad.Cont.ContT
    
    * Control.Monad.Except
        - Class: Control.Monad.Except.Class.MonadError
        - Transformer: Control.Monad.Except.ExceptT
    
    * Control.Monad.Identity
        - Transformer: Control.Monad.Trans.Identity.IdentityT
    
    * Control.Monad.RWS
        - Lazy transformer: Control.Monad.RWS.Lazy.RWST
        - Strict transformer: Control.Monad.RWS.Strict.RWST
    
    * Control.Monad.Reader
        - Class: Control.Monad.Reader.Class.MonadReader
        - Transformer: Control.Monad.Reader.ReaderT
    
    * Control.Monad.State
        - Class: Control.Monad.State.Class.MonadState
        - Lazy transformer: Control.Monad.State.Lazy.StateT
        - Strict transformer: Control.Monad.State.Strict.StateT
    
    * Control.Monad.Writer
        - Class: Control.Monad.Writer.Class.MonadWriter
        - Lazy transformers: Control.Monad.Writer.Lazy.WriterT
        - Strict transformers: Control.Monad.Writer.Strict.WriterT
    
    * Control.Monad.Accum
        - Class: Control.Monad.Accum
        - Transformer: Control.Monad.Trans.Accum.AccumT
    
    * Control.Monad.Select
        - Class: Control.Monad.Select
        - Transformer: Control.Monad.Trans.Select.SelectT