monad-levels alternatives and similar packages
Based on the "monad" category.
Alternatively, view monad-levels alternatives based on common mentions on social networks and blogs.
monad-control9.1 0.0 monad-levels VS monad-controlLift control operations, like exception catching, through monad transformers
monad-validate9.1 0.0 monad-levels VS monad-validate(NOTE: REPOSITORY MOVED TO NEW OWNER: https://github.com/lexi-lambda/monad-validate) A Haskell monad transformer library for data validation
monad-time8.9 0.0 monad-levels VS monad-timeType class for monads which carry the notion of the current time.
monad-unlift8.4 0.0 monad-levels VS monad-unliftTypeclasses for representing monad (transformer) morphisms
monad-metrics8.4 0.0 monad-levels VS monad-metricshaskell metrics
monad-unlift-ref8.4 0.0 monad-levels VS monad-unlift-refTypeclasses for representing monad (transformer) morphisms
monad-loops8.3 0.0 monad-levels VS monad-loopsSome useful control operators for looping
monad-memo7.7 0.0 monad-levels VS monad-memoMemoization monad transformer
monad-skeleton7.7 0.0 monad-levels VS monad-skeletonOperational monad library
monad-logger-prefixEasily add a prefix to your MonadLogger output.
monad-batcher7.3 0.0 monad-levels VS monad-batcherAn applicative monad that batches commands for later more efficient execution
monad-ste6.7 0.0 monad-levels VS monad-steST with efficient exceptions
monad-supply6.4 1.5 monad-levels VS monad-supplySupport for computations which consume values from a (possibly infinite) supply.
monad-classes6.1 0.0 monad-levels VS monad-classesA more flexible mtl
monad-io-adapter6.1 0.0 monad-levels VS monad-io-adapterA Haskell package that adapts between MonadIO and MonadBase IO
monad-st4.9 0.0 monad-levels VS monad-stA basic monad for lifting ST actions
monad-task4.7 0.0 monad-levels VS monad-taskTask monad transformer that turns event processing into co-routines programming.
monad-journal4.7 0.0 monad-levels VS monad-journalPure logger typeclass and monad transformer
monad-extras4.5 0.0 monad-levels VS monad-extrasExtra utility functions for working with monads
monad-resumption4.0 0.0 monad-levels VS monad-resumptionResumption and Reactive-Resumption Monads for the Haskell programming language.
monad-loops-stm3.8 0.0 monad-levels VS monad-loops-stmSTM-specific control operators (split out of monad-loops as of version 0.4)
monad-introspect2.9 0.0 monad-levels VS monad-introspectA reader monad that gives the environment access to the entire transformer stack
monad-interleave2.6 0.0 monad-levels VS monad-interleaveMonads with an unsaveInterleaveIO-like operation
monad-control-alignedLift control operations, like exception catching, through monad transformers
monad-control-identityStronger classes than monad-control
io-manager2.1 0.0 monad-levels VS io-managerSkeleton library around the IO monad.
monad-open1.9 0.0 monad-levels VS monad-openOpen-ended computation for when you need it (open recursion)
monad-peel1.9 0.0 monad-levels VS monad-peelLift control operations like exception catching through monad transformers
monad-var1.3 0.0 monad-levels VS monad-varGeneric operations over variables
monad-finally1.3 0.0 monad-levels VS monad-finallyGuard monadic computations with cleanup actions
monad-markov0.5 0.0 monad-levels VS monad-markovMarkov process monad
Access the most powerful time series database as a service
Do you think we are missing an alternative of monad-levels or a related project?
Why not mtl?
The oft-spouted problem with the standard monad transformer library mtl and similar libraries is that instances are quadratic: you need a separate instance for each valid combination of transformer + typeclass.
For end users, this isn't really a problem: after all, all the required instances have already been written for you!
But what happens if you have a custom transformer, or a custom typeclass?
What about if you want to have something like
MonadIO but for a
different base monad?
Then you need to write all those extra instances.
What makes it more frustrating is that many of the instance
definitions are identical: typically for every transformer (using
StateT s m as an example) it becomes a matter of:
Possibly unwrap the transformer from a monadic value to get the lower monad (e.g.
StateT s m a -> m (a,s));
Possibly add internal values (e.g.
m a -> m (a,s));
Wrap the lower monad from the result of the computation back up into the transformer (e.g.
m (a,s) -> StateT s m a).
Ideally, instead we'd have something along the lines of (simplified):
class (Monad m) => MonadBase m where type BaseMonad m :: * -> * liftBase :: BaseMonad m a -> m a class (MonadBase m) => MonadLevel m where type LowerMonad m :: * -> * type InnerValue m a :: * -- A continuation-based approach for how to lift/lower a monadic value. wrap :: ( (m a -> LowerMonad m (InnerValue m a) -- unwrap -> (LowerMonad m a -> LowerMonad m (InnerValue m a)) -- addInternal -> LowerMonad m (InnerValue m a) ) -> m a
With these two classes, we could then use Advanced Type Hackery (TM) to let us instead just specify instances for the transformers/monads that do have direct implementations for a typeclass, and then have the rest defined for us!
It turns out that this approach is even powerful enough to make
liftBase redundant, and it isn't limited to just lifting a monad but
can instead be used for arbitrary functions.
Minimal specification required for adding new typeclasses: just specify the instances for monads that satisfy it, and then use the provided machinery to lift/lower methods to other transformers in the monadic stack.
Works even for polyvariadic functions.
Still allows specifying whether certain transformers do not allow some constraints to pass through (e.g.
ContTdoes not allow access to a
Requires a lot of GHC extensions.
Requires usage of proxies when lifting/lowering typeclass methods.
Large usage of associated types means type errors can be difficult to decipher.
Due to usage of closed type-families, it is not possible to add extra instances to typeclasses (i.e. it is not possible to use a custom
Currently un-benchmarked; as such, it's not known how much of a performance penalty this approach takes.
Lowering polyvariadic functions requires specifying the type of the function using a specific grammar (though the common
m a -> m acase is pre-defined).