loops alternatives and similar packages
Based on the "Control" category.
Alternatively, view loops alternatives based on common mentions on social networks and blogs.
rio-orphans9.9 3.7 loops VS rio-orphansA standard library for Haskell
machines9.8 3.7 loops VS machinesNetworks of composable stream transducers
funflow9.8 0.0 loops VS funflowFunctional workflows
mtl9.8 5.8 loops VS mtlThe Monad Transformer Library
fused-effects9.8 7.0 loops VS fused-effectsA fast, flexible, fused effect system for Haskell
pipes9.8 2.1 loops VS pipesCompositional pipelines
transient9.8 0.0 loops VS transientA 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 de-inversion of control (No callbacks, no blocking, pure state)
capability9.7 3.5 loops VS capabilityExtensional capabilities and deriving combinators
recursion-schemes9.7 0.0 loops VS recursion-schemesGeneralized bananas, lenses and barbed wire
apecs9.7 0.0 loops VS apecsa fast, extensible, type driven Haskell ECS framework for games
distributed-closure9.6 0.0 loops VS distributed-closureSerializable closures for distributed programming.
freer-simple9.6 0.0 loops VS freer-simpleA friendly effect system for Haskell
record9.6 0.0 loops VS recordAnonymous records
free9.6 4.2 loops VS freefree monads
foldl9.6 0.0 loops VS foldlComposable, streaming, and efficient left folds
extensible-effects9.5 0.0 loops VS extensible-effectsExtensible Effects: An Alternative to Monad Transformers
classy-prelude9.5 0.0 loops VS classy-preludeType classes for mapping, folding, and traversing monomorphic containers
auto9.5 0.0 loops VS autoHaskell DSL and platform providing denotational, compositional api for discrete-step, locally stateful, interactive programs, games & automations. http://hackage.haskell.org/package/auto
selective9.5 1.6 loops VS selectiveSelective Applicative Functors: Declare Your Effects Statically, Select Which to Execute Dynamically
unliftio9.5 2.8 loops VS unliftioThe MonadUnliftIO typeclass for unlifting monads to IO
classy-prelude-yesod9.5 0.0 loops VS classy-prelude-yesodType classes for mapping, folding, and traversing monomorphic containers
safe-exceptions9.5 0.0 loops VS safe-exceptionsSafe, consistent, and easy exception handling
abstract-par9.4 0.0 loops VS abstract-parType classes generalizing the functionality of the 'monad-par' library.
these9.4 1.0 loops VS theseAn either-or-both data type, with corresponding hybrid error/writer monad transformer.
hask9.4 0.0 loops VS haskCategory theory for Haskell with a lens flavor (you need GHC 7.8.3, not 7.8.2 to build this!)
ComonadSheet9.4 0.0 loops VS ComonadSheetA library for expressing "spreadsheet-like" computations with absolute and relative references, using fixed-points of n-dimensional comonads.
retry9.4 0.0 loops VS retryRetry combinators for monadic actions that may fail
frpnow9.3 0.0 loops VS frpnowPrincipled practical FRP
parallel9.3 1.6 loops VS parallela library for parallel programming
transient-universe9.3 0.0 loops VS transient-universeA 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
cloud-haskell9.2 0.0 loops VS cloud-haskellThis is an umbrella development repository for Cloud Haskell
deepseq9.2 4.0 loops VS deepseqDeep evaluation of data structures
distributed-process-platformDEPRECATED (Cloud Haskell Platform) in favor of distributed-process-extras, distributed-process-async, distributed-process-client-server, distributed-process-registry, distributed-process-supervisor, distributed-process-task and distributed-process-execution
distributed-fork9.2 0.0 loops VS distributed-forkA distributed data processing framework in Haskell.
ifcxt9.1 0.0 loops VS ifcxtconstraint level if statements
tardis9.1 0.0 loops VS tardisBidirectional state monad transformer
monad-validate9.1 0.0 loops VS monad-validate(NOTE: REPOSITORY MOVED TO NEW OWNER: https://github.com/lexi-lambda/monad-validate) A Haskell monad transformer library for data validation
either9.1 0.0 loops VS eitherthe EitherT monad transformer
contravariant9.1 1.6 loops VS contravariantHaskell 98 contravariant functors
monad-control9.1 0.0 loops VS monad-controlLift control operations, like exception catching, through monad transformers
ixmonad9.0 0.0 loops VS ixmonadProvides 'graded monads' and 'parameterised monads' to Haskell, enabling fine-grained reasoning about effects.
errors9.0 0.0 loops VS errorsType-safe error handling
effect-monad9.0 0.0 loops VS effect-monadProvides 'graded monads' and 'parameterised monads' to Haskell, enabling fine-grained reasoning about effects.
freer-effects9.0 0.0 loops VS freer-effectsAn implementation of "Freer Monads, More Extensible Effects".
operational9.0 0.0 loops VS operationalImplement monads by specifying instructions and their desired operational semantics.
objective8.9 2.9 loops VS objectivePurely functional objects
motor8.9 0.0 loops VS motorType-safe effectful state machines in Haskell
exceptions8.9 0.0 loops VS exceptionsmtl friendly exceptions
monad-time8.9 0.0 loops VS monad-timeType class for monads which carry the notion of the current time.
mmorph8.9 0.0 loops VS mmorphMonad morphisms
Clean code begins in your IDE with SonarLint
Do you think we are missing an alternative of loops or a related project?
Loops have the structure of a monad. Bind (
>>=) nests loops and
return x is
a loop with a single iteration over a value
- Fast, imperative-style loops with a clean syntax. Bind (
>>=) nests loops, so in
do-notation, each subsequent line is nested inside loops that appear above it.
- Iteration over common data structures, like lists and vectors.
- Robust performance because there is no reliance on fusion.
- Loop-unrolling to arbitrary depth. Unrollable loop combinators are
Control.Monad.Loop.Unroll. (The simple, "rolled" interface is still provided in
Control.Monad.Loop.) The unrolling depth is set at the call site at compile time. My benchmarks show that folding over unrolled loops is up to 25% faster than folding over unboxed vectors!
- NEW! Arbitrary, named continuations (breakpoints).
breaking_each create a continuation at the current point and pass that continuation to a subloop. The named continuation is existentially quantified to prevent it from escaping its scope. Only one continuation/breakpoint can be active at a time.
unbreakablemasks continuations, preventing any external breakpoints from being invoked in a subloop.
For best performance, please compile your code with
-O2. You should also use
GHC's LLVM backend if possible; it generally produces faster executables.
A silly example
At first, the statement that "bind nests loops" may seem strange, but can be
motivated by the
Monad instance for lists. Consider the following
do-notation for a list:
module Example where import Control.Monad.Loop import Data.Foldable (toList) -- A list of pairs (i, j) where 0 <= i <= 3 and 0 <= j <= i nestedList :: [(Int, Int)] nestedList = do i <- [0..3] j <- [0..i] return (i, j)
If you're not familiar with this use of lists, load up this file in ghci
ghci -isrc -pgmL markdown-unlit README.lhs. (You need to have
markdown-unlit installed first.)
nestedList at the prompt and see:
>>> nestedList [(0,0),(1,0),(1,1),(2,0),(2,1),(2,2),(3,0),(3,1),(3,2),(3,3)]
Now let's do something really silly: let's build the same list with a
nestedList' :: [(Int, Int)] nestedList' = toList $ loop $ do -- 'loop' is just an aid to type inference i <- for 0 (<= 3) (+ 1) j <- for 0 (<= i) (+ 1) return (i, j)
You would never actually want to do this. This example is simply to illustrate what "bind nests loops" means in a context most Haskellers are familiar with.
The correspondence between the list monad and the loop monad is not a
coincidence! GHC uses stream fusion to reduce (some) uses of lists to simple
loops so that the evaluated list is never held in memory. Unfortunately, using
lists as loops is dangerous in performance-sensitive code because the fusion
rules may fail to fire, leaving you with a fully-evaluated list on the heap! A
Loop can only evaluate one iteration at a time, so there is no larger data
structure that needs to be fused. Consequently, performance is less fragile.
You might complain that this style of programming does not fit Haskell very
well, but I would contend just the opposite. As I mentioned above, lists are the
more general case of loops: a list can be just a plain loop (fused), or it can
be all the iterations of the loop held in memory at once. In fact, lists admit
some operations (like
reverse) that prevent fusion, but
Loop has a refined
type that only allows construction of fusible operations! This is exactly where
Haskell shines: the type system prevents incorrect (or in this case,
undesirable) programs from being written. I see this as part of a (relatively
recent) trend in Haskell toward using the type system to guarantee performance
in addition to correctness.