1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | {-# LANGUAGE BangPatterns #-} module Main ( main ) where import Data.IORef -- | An emulation of a C for loop. -- -- for (first clause; second clause; third clause) { loop body } for :: Monad m => a -- ^ First clause. -> (a -> Bool) -- ^ Second clause. -> (a -> a) -- ^ Third clause. -> (a -> m b) -- Loop body. Return value ignored for convenience. -> m () for start cond inc body = go start where go !n | cond n = body n >> go (inc n) | otherwise = return () {-# INLINE for #-} main = do x <- newIORef 0 for 0 (<1000000) (+1) $ \i -> modifyIORef x (+i) print =<< readIORef x |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | -- 17.5% productivity, and stack overflows. {-# LANGUAGE BangPatterns #-} module Main ( main ) where import Data.IORef -- | An emulation of a C for loop. -- -- for (first clause; second clause; third clause) { loop body } for :: Monad m => a -- ^ First clause. -> (a -> Bool) -- ^ Second clause. -> (a -> a) -- ^ Third clause. -> (a -> m b) -- Loop body. Return value ignored for convenience. -> m () for start cond inc body = go start where go !n | cond n = body n >> go (inc n) | otherwise = return () {-# INLINE for #-} main = do x <- newIORef 0 for 0 (<1000000) (+1) $ \i -> modifyIORef x (+i) print =<< readIORef x |