Brandon S. Allbery KF8NH allbery at ece.cmu.edu
Sat Nov 1 12:02:41 EDT 2008

```On 2008 Nov 1, at 12:23, Larry Evans wrote:
> That still leaves me confused about:
>
> put (n+1)
> AFAICT, with the preceding |n <- get|, this means:
>
> put (get+1)

The <- syntax (actually (>>=)) "unwraps" a monadic value (on condition
that it is "rewrapped" later), so instead of |State Int Int| it's just
|Int|.

> I'm trying to understand how to use MonadState. I would have
> expected tick would have been defined:
>
> tick = State (\n -> (n+1,n+1))

I think you meant \n -> (n,n+1)

>
> instead of the more obscure:
>
> tick = do n <- get
>           put (n+1)
>           return n

The above translates to

get >>= \n -> put (n+1) >> return n

Expand (>>=):

State (\s -> let (a,s') = runState get s
in runState (put (a+1)) s')

Expand |get| and |put|:

State (\s -> let (a,s') = runState (State (\s'' -> (s'',s'')))
in runState (State (\_ -> ((),a+1))) s')

|runState| and |State| cancel:

State (\s -> let (a,s') = (\s'' -> (s'',s''))
in (\_ -> (s',a+1)))

Now expand the inner lambdas:

State (\s -> let (a,s') = (s,s)
in (s',a+1))

And collapse the let:

State (\s -> (s,s+1))

(I think I did that right; at least I got the right result...)

The point of using the "more obscure" definition is that it uses the
machinery already defined for |State| --- and (given that I'm not
absolutely certain I expanded the above right!) using the machinery is
easier to keep track of than expanding directly, while demonstrating
the operation of |State| instead of just presenting a result without
explanation of how it follows from the definition of |State|.

--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery at kf8nh.com
system administrator [openafs,heimdal,too many hats] allbery at ece.cmu.edu
electrical and computer engineering, carnegie mellon university    KF8NH

```