Skip to content

forM_ [1..N] does not get fused (allocates 50% more)

Apparently idiomatic code like forM_ [1.._N] does not get fused away.

This can give serious performance problems when unnoticed.

-- Slow:
forM_ [0.._N-1] $ \i -> do ...

-- Around 10 times faster:
loop _N $ \i -> do ...

{-# INLINE loop #-}
loop :: (Monad m) => Int -> (Int -> m ()) -> m ()
loop bex f = go 0
  where
    go !n | n == bex = return ()
          | otherwise = f n >> go (n+1)

Full code example: https://gist.github.com/nh2/8905997 - the relevant alternatives are commented.

Edited by george.colpitts
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information