loops alternatives and similar packages
Based on the "Control" category.
Alternatively, view loops 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) 
classyprelude
Type classes for mapping, folding, and traversing monomorphic containers 
classypreludeyesod
Type classes for mapping, folding, and traversing monomorphic containers 
distributedclosure
Serializable closures for distributed programming. 
extensibleeffects
Extensible Effects: An Alternative to Monad Transformers 
abstractpar
Type classes generalizing the functionality of the 'monadpar' library. 
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 
these
An eitherorboth data type, with corresponding hybrid error/writer monad transformer. 
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!) 
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 
distributedfork
A distributed data processing framework in Haskell. 
monadvalidate
(NOTE: REPOSITORY MOVED TO NEW OWNER: https://github.com/lexilambda/monadvalidate) A Haskell monad transformer library for data validation 
distributedprocessplatform
DEPRECATED (Cloud Haskell Platform) in favor of distributedprocessextras, distributedprocessasync, distributedprocessclientserver, distributedprocessregistry, distributedprocesssupervisor, distributedprocesstask and distributedprocessexecution 
monadtime
Type class for monads which carry the notion of the current time. 
monadcontrol
Lift control operations, like exception catching, through monad transformers 
effectmonad
Provides 'graded monads' and 'parameterised monads' to Haskell, enabling finegrained reasoning about effects. 
freereffects
An implementation of "Freer Monads, More Extensible Effects". 
ixmonad
Provides 'graded monads' and 'parameterised monads' to Haskell, enabling finegrained reasoning about effects. 
operational
Implement monads by specifying instructions and their desired operational semantics.
Onboard AI  ChatGPT with full context of any GitHub repo.
Do you think we are missing an alternative of loops or a related project?
README
loops
Academic Summary
Loops have the structure of a monad. Bind (>>=
) nests loops and return x
is
a loop with a single iteration over a value x
.
Features
 Fast, imperativestyle loops with a clean syntax. Bind (
>>=
) nests loops, so indo
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.
 Loopunrolling to arbitrary depth. Unrollable loop combinators are
provided in
Control.Monad.Loop.Unroll
. (The simple, "rolled" interface is still provided inControl.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
andbreaking_
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.unbreakable
masks continuations, preventing any external breakpoints from being invoked in a subloop.
Performance
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
with ghci isrc pgmL markdownunlit README.lhs
. (You need to have
markdownunlit installed first.)
Enter 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
Loop
!
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 performancesensitive code because the fusion
rules may fail to fire, leaving you with a fullyevaluated 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.