Roberto Zunino roberto.zunino at sns.it
Mon Nov 21 10:09:41 EST 2005

```Yitzchak Gale wrote:

> In the following, why does testA work and testB diverge?
> Where is the strictness coming from?

My guess: from strict pattern matching in (>>=).

The following StateT variant uses lazy (irrefutable) pattern match instead.

Regards,
Roberto Zunino.

====
newtype StT s m a = StT { runStT :: s -> m (a,s) }

instance (Monad m) => Monad (StT s m) where
return a = StT \$ \s -> return (a, s)
m >>= k  = StT \$ \s -> do
-- was: (a, s') <- runStT m s
~(a, s') <- runStT m s
runStT (k a) s'
fail str = StT \$ \_ -> fail str

stGet :: Monad m => StT s m s
stGet = StT \$ \s -> return (s,s)

stPut :: Monad m => s -> StT s m ()
stPut s = StT \$ \_ -> return ((),s)

evalStT :: Monad m => StT s m a -> s -> m a
evalStT m s = do (x,_) <- runStT m s ; return x

repeatM :: Monad m => m a -> m [a]
repeatM = sequence . repeat

testC =
take 5 \$
runIdentity \$
flip evalStT [1..10] \$ repeatM \$ do
s <- stGet
let x = head s
stPut \$ tail s
return x
====
```