MyNixOS website logo
Description

Lift substacks of monad transformer stacks.

mtl-uplift

Hackage

Uplift entire substacks of monad transformer stacks, boilerplate free!

Many industry Haskell programmers are all too familiar with code like:

lift . lift . lift . lift . lift . lift . lift . lift . lift . lift . lift . lift . lift $ do
  blah

This may or may not be an exaggeration. Now, we can just write the much less visually annoying:

uplift @TopOfSubstackT $ do
  blah

This relieves the programmer from having to do any bookkeeping about what level of their greater stack their substack lives at, but just to know which monad tops it. Beyond that, if we transform our stack, with the old code we would potentially have to modify the number of calls to lift, but now, as long as we still want to uplift a substack with the same top, we don't have to. Isn't that uplifting?

Here is a more complete example from the tests:

{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE BlockArguments #-}
module Main where

import Control.Monad.Trans.Uplift

import Control.Monad.State
import Control.Monad.Writer
import Control.Monad.Reader

type Stack = StateT Bool (WriterT [String] (ReaderT Char IO))

runStack :: Stack a -> IO (a, [String])
runStack stack = runReaderT (runWriterT (evalStateT stack True)) 'X'

main :: IO ()
main = do
  (a, xs) <- runStack do
    uplift @(WriterT [String]) do
      tell ["One", "Two"]
      c <- uplift @(ReaderT Char) ask
      if c == 'X' then tell ["One, Two, Three, Four"]
      else pure ()
  guard (xs == ["One", "Two", "One, Two, Three, Four"])
Metadata

Version

0.1.0.1

License

Platforms (75)

    Darwin
    FreeBSD
    Genode
    GHCJS
    Linux
    MMIXware
    NetBSD
    none
    OpenBSD
    Redox
    Solaris
    WASI
    Windows
Show all
  • aarch64-darwin
  • aarch64-genode
  • aarch64-linux
  • aarch64-netbsd
  • aarch64-none
  • aarch64_be-none
  • arm-none
  • armv5tel-linux
  • armv6l-linux
  • armv6l-netbsd
  • armv6l-none
  • armv7a-darwin
  • armv7a-linux
  • armv7a-netbsd
  • armv7l-linux
  • armv7l-netbsd
  • avr-none
  • i686-cygwin
  • i686-darwin
  • i686-freebsd
  • i686-genode
  • i686-linux
  • i686-netbsd
  • i686-none
  • i686-openbsd
  • i686-windows
  • javascript-ghcjs
  • loongarch64-linux
  • m68k-linux
  • m68k-netbsd
  • m68k-none
  • microblaze-linux
  • microblaze-none
  • microblazeel-linux
  • microblazeel-none
  • mips-linux
  • mips-none
  • mips64-linux
  • mips64-none
  • mips64el-linux
  • mipsel-linux
  • mipsel-netbsd
  • mmix-mmixware
  • msp430-none
  • or1k-none
  • powerpc-netbsd
  • powerpc-none
  • powerpc64-linux
  • powerpc64le-linux
  • powerpcle-none
  • riscv32-linux
  • riscv32-netbsd
  • riscv32-none
  • riscv64-linux
  • riscv64-netbsd
  • riscv64-none
  • rx-none
  • s390-linux
  • s390-none
  • s390x-linux
  • s390x-none
  • vc4-none
  • wasm32-wasi
  • wasm64-wasi
  • x86_64-cygwin
  • x86_64-darwin
  • x86_64-freebsd
  • x86_64-genode
  • x86_64-linux
  • x86_64-netbsd
  • x86_64-none
  • x86_64-openbsd
  • x86_64-redox
  • x86_64-solaris
  • x86_64-windows