loop-0.2.0: Fast loops (for when GHC can't optimize forM_)

Safe HaskellSafe-Inferred

Control.Loop

Description

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).

Synopsis

Documentation

forLoop :: Monad m => a -> (a -> Bool) -> (a -> a) -> (a -> m ()) -> m ()Source

forLoop start cond inc f: A C-style for loop with starting value, loop condition and incrementor.

forLoopFold :: a -> (a -> Bool) -> (a -> a) -> acc -> (acc -> a -> acc) -> accSource

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.

numLoop :: (Num a, Eq a, Monad m) => a -> a -> (a -> m ()) -> m ()Source

numLoop start end f: Loops over a contiguous numerical range, including end.

It uses (+ 1) so for most integer types it has no bounds (overflow) check.

numLoopFold :: (Num a, Eq a) => a -> a -> acc -> (acc -> a -> acc) -> accSource

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.