Sorry, thought I had replied to this with my result!

I added `seq` and $! inside `stuffToDo` to ensure that there weren't any thunks left around after it was called.

The measured times were only a few hundredths of a second apart after that.

So, apparently even with a strict StateT, partially evaluated references can easily be left around all the way until the call to runStateT returns. In this case my state is a record, if that makes any difference. It's not what I expected... I can see why my example is too small to show why it behaved this way though.

I thought pattern matching (in Haskell98) was itself strict, so I don't see what the difference between a lazy and strict stateT is, except perhaps in cases that the value of runStateT is bound via a different mechanism than pattern matching. 

On Sat, Oct 22, 2011 at 6:13 AM, Daniel Fischer <daniel.is.fischer@googlemail.com> wrote:
On Saturday 22 October 2011, 13:55:36, Bas van Dijk wrote:
> On 20 October 2011 22:16, thomas burt <thedwards@gmail.com> wrote:
> > Perhaps I will try and force `stuffToDo` not to leave any partially
> > evaluated thunks behind.... and compare the cost then.
>
> What happens when you switch to a strict StateT?

He already uses the strict StateT:

> By the way I'm using ghc-6.10.4 and Control.Monad.Trans.State.Strict.

We need to see more of the code to find out what's going on.