inotherwords alternatives and similar packages
Based on the "Control" category.
Alternatively, view inotherwords alternatives based on common mentions on social networks and blogs.

transient
A full stack, reactive architecture for general purpose programming. Algebraic and monadically composable primitives for concurrency, parallelism, event handling, transactions, multithreading, Web, and distributed computing with complete deinversion of control (No callbacks, no blocking, pure state) 
fusedeffects
A fast, flexible, fused effect system for Haskell 
recursionschemes
Generalized bananas, lenses and barbed wire 
apecs
a fast, extensible, type driven Haskell ECS framework for games 
distributedclosure
Serializable closures for distributed programming. 
classypreludeyesod
Type classes for mapping, folding, and traversing monomorphic containers 
extensibleeffects
Extensible Effects: An Alternative to Monad Transformers 
classyprelude
Type classes for mapping, folding, and traversing monomorphic containers 
selective
Selective Applicative Functors: Declare Your Effects Statically, Select Which to Execute Dynamically 
auto
Haskell DSL and platform providing denotational, compositional api for discretestep, locally stateful, interactive programs, games & automations. http://hackage.haskell.org/package/auto 
safeexceptions
Safe, consistent, and easy exception handling 
ComonadSheet
A library for expressing "spreadsheetlike" computations with absolute and relative references, using fixedpoints of ndimensional comonads. 
hask
Category theory for Haskell with a lens flavor (you need GHC 7.8.3, not 7.8.2 to build this!) 
abstractpar
Type classes generalizing the functionality of the 'monadpar' library. 
these
An eitherorboth data type, with corresponding hybrid error/writer monad transformer. 
transientuniverse
A Cloud monad based on transient for the creation of Web and reactive distributed applications that are fully composable, where Web browsers are first class nodes in the cloud 
cloudhaskell
This is an umbrella development repository for Cloud Haskell 
distributedprocessplatform
DEPRECATED (Cloud Haskell Platform) in favor of distributedprocessextras, distributedprocessasync, distributedprocessclientserver, distributedprocessregistry, distributedprocesssupervisor, distributedprocesstask and distributedprocessexecution 
distributedfork
A distributed data processing framework in Haskell. 
monadcontrol
Lift control operations, like exception catching, through monad transformers 
monadvalidate
(NOTE: REPOSITORY MOVED TO NEW OWNER: https://github.com/lexilambda/monadvalidate) A Haskell monad transformer library for data validation 
ixmonad
Provides 'graded monads' and 'parameterised monads' to Haskell, enabling finegrained reasoning about effects. 
effectmonad
Provides 'graded monads' and 'parameterised monads' to Haskell, enabling finegrained reasoning about effects. 
monadtime
Type class for monads which carry the notion of the current time. 
freereffects
An implementation of "Freer Monads, More Extensible Effects". 
operational
Implement monads by specifying instructions and their desired operational semantics. 
lenstutorial
The missing tutorial module for the lens library
Build timeseriesbased applications quickly and at scale.
Do you think we are missing an alternative of inotherwords or a related project?
README
inotherwords
 Overview
 Features
 Required Language Extensions
 Examples of Simple Usage
 Advanced Usage
 Troubleshooting
 Performance
Overview
inotherwords
is an effect system in the vein of freersimple
,
fusedeffects
,
polysemy
,
and eff
. It represents effects through data types,
making it simple to define, use, and interpret them.
The goal of inotherwords
is to be as expressive and general of an
effect system as possible while solving the O(n2) instances
problem. Its hallmark feature is the novel approach it takes to support
higherorder effects, making it significantly more powerful  and sometimes
easier to use  than other effect libraries of its kind.
If you're experienced with the mechanisms behind freersimple
,
fusedeffects
, and polysemy
, and would like to learn more about what makes
inotherwords
different, see
this wiki page.
Unfortunately, in its current state inotherwords
is rather inaccessible.
Ample documentation and guides are provided for the library, but inexperienced
users are still likely to run into gotchas that result in very
confusing error messages. As such, if you're a beginner to effect systems,
freersimple
or polysemy
would serve as better starting points.
Features
Simple higherorder effects
Unlike fusedeffects
and polysemy
 which both have intimidating
boilerplate associated with the interpretation of higherorder effects
inotherwords
makes it just as easy to interpret higherorder effects as
firstorder effects. Go here for an example.
No cumbersome restrictions to effects
Every effect system previously mentioned has serious restrictions in what effects they may represent.
freersimple
is restricted to firstorder effects.fusedeffects
andpolysemy
are built around Effect Handlers in Scope, whose approach doesn't allow for sensible implementations of effects for continuations, coroutines, or nondeterminism.eff
is limited to what's implementable with delimited continuations, which excludes actions such aspass
fromMonadWriter
, andasync
/await
style concurrency.
inotherwords
also places restrictions on what effects may be represented
 but in contrast to the libraries mentioned above, these restrictions are
almost completely negligable.1 This is possible because
unlike most other effect systems, inotherwords
does not attempt to make
every possible effect play nicely together with every other effect: instead,
just like mtl
, some effects can't be used together with other effects
(depending on how they're interpreted),
and this is enforced by constraints that interpreters may introduce.
Required Language Extensions
The following extensions are needed for basic usage of the library:
 ConstraintKinds
 DataKinds
 FlexibleContexts
 GADTs
 LambdaCase
 PolyKinds
 RankNTypes
 TypeApplications
 TypeOperators
 TypeFamilies
Some features of the library could require enabling more extensions.
Examples of Simple Usage
Firstorder usage:
import Control.Effect
import Control.Effect.Error
import Control.Effect.State
import Control.Effect.Reader
import Control.Effect.Writer
import Text.Read (readMaybe)
data Teletype m a where
ReadTTY :: Teletype m String
WriteTTY :: String > Teletype m ()
readTTY :: Eff Teletype m => m String
readTTY = send ReadTTY
writeTTY :: Eff Teletype m => String > m ()
writeTTY str = send (WriteTTY str)
challenge :: Eff Teletype m => m ()
challenge = do
writeTTY "What is 3 + 4?"
readTTY >>= \str > case readMaybe @Int str of
Just 7 > writeTTY "Correct!"
_ > writeTTY "Nope." >> challenge
 Interpret a Teletype effect in terms of IO operations
teletypeToIO :: Eff (Embed IO) m => SimpleInterpreterFor Teletype m
teletypeToIO = interpretSimple $ \case
ReadTTY > embed getLine  use 'embed' to lift IO actions.
WriteTTY msg > embed $ putStrLn msg
 Make a challenge to the user
challengeIO :: IO ()
challengeIO = runM $ teletypeToIO $ challenge
 Interpret a `Teletype` effect in terms of `Ask` and `Tell` effects
runTeletype :: Effs '[Ask String, Tell String] m
=> SimpleInterpreterFor Teletype m
runTeletype = interpretSimple $ \case
ReadTTY > ask
WriteTTY msg > tell msg
 Runs a challenge with the provided inputs purely.
challengePure :: [String] > Either String [String]
challengePure testInputs =
 Extract the final result, now that all effects have been interpreted.
run
 Run the @Throw [email protected] effect, resulting in @Either String [String]@
$ runThrow @String
 We discard the return value of @[email protected]  () 
 while retaining the list of told strings.
$ fmap fst
 Run the @Tell [email protected] effect by gathering all told
 strings into a list, resulting in ([String], ())
$ runTellList @String
 Run the @State [String]@ effect with initial state
 @[email protected] @[email protected] discards the end state.
$ evalState testInputs
 Interpret the @Ask [email protected] effect by going through the provided inputs
 one by one.
 Throw an exception if we go through all the inputs without completing the
 challenge.
$ runAskActionSimple (do
get >>= \case
[] > throw "Inputs exhausted!"
(x:xs) > put xs >> return x
)
 Interpret @[email protected] in terms of @Ask [email protected] and @Tell [email protected]
$ runTeletype
 Run the main program @[email protected], which returns ()
$ challenge
 evaluates to True
testChallenge :: Bool
testChallenge =
challengePure ["4","7", "i dunno", "7"]
== Right ["What is 3 + 4?", "Nope."
,"What is 3 + 4?", "Nope."
,"What is 3 + 4?", "Nope."
,"What is 3 + 4?", "Correct!"
]
Higherorder usage:
import Control.Effect
import Control.Effect.Bracket
import Control.Effect.Trace
import GHC.Clock (getMonotonicTime)
data ProfileTiming m a where
ProfileTiming :: String > m a > ProfileTiming m a
time :: Eff ProfileTiming m => String > m a > m a
time label m = send (ProfileTiming label m)
 Interpret a ProfileTiming effect in terms of IO operations,
 'Trace', and 'Bracket'.
profileTimingToIO :: Effs '[Embed IO, Trace, Bracket] m
=> SimpleInterpreterFor ProfileTiming m
profileTimingToIO = interpretSimple $ \case
ProfileTiming label action > do
before < embed getMonotonicTime
 To execute a provided computation when interpreting a
 higherorder effect, just bind it.
 You can also use other higherorder effects to interact with it!
a < action
`onError`  Provided by 'Bracket'
trace ("Timing of " ++ label ++ " failed due to some error!")
after < embed getMonotonicTime
trace ("Timing of " ++ label ++ ": " ++ show (after  before) ++ " seconds.")
return a
spin :: Monad m => Integer > m ()
spin 0 = pure ()
spin i = spin (i  1)
profileSpin :: IO ()
profileSpin = runM $ bracketToIO $ runTracePrinting $ profileTimingToIO $ do
time "spin" (spin 1000000)
time "spinAndFail" (spin 1000000 >> undefined)
{
This prints the following (exact times are machine specific):
Timing of spin: 1.3399935999768786 seconds.
Timing of spinAndFail failed due to some error!
*** Exception: Prelude.undefined
}
Advanced Usage
The examples above are somewhat disingenuous; they cover only the simplest
uses of the library. The library has a wide variety of features,
and using them properly can get very complicated. Because of this,
inotherwords
offers a wiki covering more advanced topics of the
library.
Check it out if you're interested in learning more about the
library, or are struggling with a feature.
Troubleshooting
The wiki has a page for common error messages. If you run into any issues or strange error messages that you can't figure out from the wiki, feel free to make an issue about it. If not already covered, and if I can generalize the problem enough, then I'll expand the wiki to cover the issue.
Performance
In the microbenchmarks offered by effectszoo
inotherwords
performs comparably to mtl
and fusedeffects
;
at worst up to 2x slower than fusedeffects
.
Keep in mind, however, that these are only microbenchmarks, and may not
predict performance in the wild with perfect accuracy.
The benchmark results are available here.
inotherwords
is, like mtl
and fusedeffects
, limited
by how effectively the compiler is able to optimize away the
underlying abstractions.
As noted by Alexis King,
the ideal situations under which these libraries are truly zerocost are unrealistic
in practice. Although this does adversely affect inotherwords
,
the underlying dispatch cost of effects should be low enough to make
to it largely negligable for most purposes  in particular, IObound
applications.
Further benchmarking, profiling, and optimizations are currently considered future goals of the library.
1 Every effect is required to be representational in the carrier monad. This means that if you can represent your effect using:
 a
mtl
style effect class  without any associated type families
 and it can be newtype derived
then you can also represent your effect with inotherwords
.