{-# LANGUAGE BangPatterns #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE FlexibleContexts #-} module Main where import Prelude import qualified Foreign.Storable as Storable import qualified Control.Monad.State.Strict as S import Control.Monad.IO.Class import Foreign.Marshal.Alloc (mallocBytes) newtype Foo a = Foo a intSize :: Int intSize = Storable.sizeOf (undefined :: Int) -- This 'go' loop should allocate nothing, because it specialises -- for the shape of the state. But in 8.4 it did (Trac #14936) slow :: Int -> IO () slow i = do let go 0 = pure () go j = do Foo (!a, !off) <- S.get S.put (Foo (a+1, off)) go (j - 1) S.evalStateT (go i) (Foo ((0::Int),(intSize::Int))) main = do { slow (10 ^ 7); print "Done" }