loop package:loop
Fast loops (for when GHC can't optimize forM_)
loop start end f: Loops from
start to
end
(inclusive), executing
f on each iteration. Same as
forM_
[start..end] f.
Uses
succ inside, which does a bounds (overflow) check.
Provides a convenient and fast alternative to the common
forM_
[1..n] idiom, which in many cases GHC cannot fuse to efficient
code.
Notes on fast iteration:
- For Int, (+1) is almost twice as fast as
succ because succ does an overflow check.
- For Int, you can get around that while still using
Enum using toEnum . (+ 1) . fromEnum.
- However, toEnum . (+ 1) . fromEnum is slower than
succ for Word32 on 64-bit machines since toEnum
has to check if the given Int exceeds 32 bits.
- Using (+1) from Num is always the fastest way, but
it gives no overflow checking.
- Using forLoop you can flexibly pick the way of increasing
the value that best fits your needs.
- The currently recommended replacement for forM_ [1..n] is
forLoop 1 (<= n) (+1).
forLoop start cond inc f: A C-style for loop with starting
value, loop condition and incrementor.
forLoopFold start cond inc acc0 f: A pure fold using a for
loop instead of a list for performance.
Care is taken that acc0 not be strictly evaluated if unless
done so by f.
forLoopState start cond inc initialState f: A C-style for
loop with starting value, loop condition, incrementor and a state that
is threaded through the computation.
numLoop start end f: Loops over a contiguous numerical range,
including end.
Does nothing when not start <= end.
It uses (+ 1) so for most integer types it has no bounds
(overflow) check.
numLoopFold start end acc0 f: A pure fold over a contiguous
numerical range, including end.
It uses (+ 1) so for most integer types it has no bounds
(overflow) check.
Care is taken that acc0 not be strictly evaluated if unless
done so by f.
numLoopState start end f initialState: Loops over a
contiguous numerical range, including end threading a state
through the computation.
It uses (+ 1) so for most integer types it has no bounds
(overflow) check.
Like
loop, but (sometimes) without bounds (overflow) check.
This circumvents the implementation of
succ for the
Enum type and uses
toEnum . (+ 1) . fromEnum
instead, so it will break on Enums that are not contiguous.
Note that some types (e.g. Word32) have bounds checks even for
toEnum.