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.