lpsmith / postgresql-simple

Mid-level client library for accessing PostgreSQL from Haskell
Other
206 stars 71 forks source link

`foldM'` and `forM'` contain redundant bangs. #197

Closed effectfully closed 9 months ago

effectfully commented 7 years ago

Here are the definitions:

forM' :: (Ord n, Num n) => n -> n -> (n -> IO a) -> IO [a]
forM' lo hi m = loop hi []
  where
    loop !n !as
      | n < lo = return as
      | otherwise = do
           a <- m n
           loop (n-1) (a:as)
{-# INLINE forM' #-}

foldM' :: (Ord n, Num n) => (a -> n -> IO a) -> a -> n -> n -> IO a
foldM' f a lo hi = loop a lo
  where
    loop a !n
      | n > hi = return a
      | otherwise = do
           a' <- f a n
           loop a' (n+1)
{-# INLINE foldM' #-}

There is no need to force n in both the functions, because it gets forced in n > hi. There is no need to force as in forM', because it's already always in WHNF.

lpsmith commented 7 years ago

You are correct in that none of those bang patterns are critically important, but I very much doubt that removing them would result in the same code being generated across many different versions of GHC, and I would expect that in most cases, the bangs do result in slightly better code being generated.

But yes, the emphasis is on slight here.