Control.Monad.State: State CTOR unneeded to create a State?

Page: http://hackage.haskell.org/packages/archive/mtl/latest/doc/html/Control-Mona... suggests, with the content: Constructors State runState :: (s -> (a, s)) that State has a labeled constructor: http://www.haskell.org/onlinereport/exps.html#sect3.15.2 yet the Examples section: http://hackage.haskell.org/packages/archive/mtl/latest/doc/html/Control-Mona... shows, AFAICT, no call to the State CTOR: tick :: State Int Int tick = do n <- get put (n+1) return n I assume the n must be an Int (since it's in n+1), but what are the get and put. There is a get and put described here: http://hackage.haskell.org/packages/archive/mtl/latest/doc/html/Control-Mona... however, I don't see how they are relevant since they are defined for an already existing MonadState, and AFAICT, tick hasn't been defined yet since it's on the lhs of the =. Please, what am I missing? TIA -regards Larry

On Thu, Oct 30, 2008 at 10:07 PM, Larry Evans
Page:
http://hackage.haskell.org/packages/archive/mtl/latest/doc/html/Control-Mona...
suggests, with the content:
Constructors State runState :: (s -> (a, s)) that State has a labeled constructor:
http://www.haskell.org/onlinereport/exps.html#sect3.15.2
yet the Examples section:
http://hackage.haskell.org/packages/archive/mtl/latest/doc/html/Control-Mona...
shows, AFAICT, no call to the State CTOR:
tick :: State Int Int tick = do n <- get put (n+1) return n I assume the n must be an Int (since it's in n+1), but what are the get and put. There is a get and put described here:
http://hackage.haskell.org/packages/archive/mtl/latest/doc/html/Control-Mona...
however, I don't see how they are relevant since they are defined for an already existing MonadState, and AFAICT, tick hasn't been defined yet since it's on the lhs of the =.
Please, what am I missing?
Hi Larry. Event thought 'get' and 'put' are defined in MonadState, the concrete implementation of them for "State s a" uses the 'State' constructor. They probably look something like so: get = State (\s -> (s,s)) put newS = State (\oldS ->( (), newS )) Also, the definitions of the 'Monad' class functions also need to use the 'State' constructor, for example return should look something like: return x = State (\s -> (x, s)) So when you use expressions in a 'do' block, or 'get' or 'put' then under the hood you're using the 'State' constructor. Then at the top-level you use 'runState :: State s a -> s -> (a,s)' to strip the constructor away. As long as you aren't writing anything that needs to dig to much into the workings of 'State', you shouldn't have to worry too much about it. I hope I haven't made things more confused ^_^ -Antoine

On 10/30/08 21:20, Antoine Latter wrote:
On Thu, Oct 30, 2008 at 10:07 PM, Larry Evans
wrote: Page:
http://hackage.haskell.org/packages/archive/mtl/latest/doc/html/Control-Mona...
suggests, with the content:
Constructors State runState :: (s -> (a, s)) that State has a labeled constructor:
http://www.haskell.org/onlinereport/exps.html#sect3.15.2
yet the Examples section:
http://hackage.haskell.org/packages/archive/mtl/latest/doc/html/Control-Mona...
shows, AFAICT, no call to the State CTOR:
tick :: State Int Int tick = do n <- get put (n+1) return n I assume the n must be an Int (since it's in n+1), but
what are
the get and put. There is a get and put described here:
http://hackage.haskell.org/packages/archive/mtl/latest/doc/html/Control-Mona...
however, I don't see how they are relevant since they are defined for an already existing MonadState, and AFAICT, tick hasn't been defined yet since it's on the lhs of the =.
Please, what am I missing?
Hi Larry. Event thought 'get' and 'put' are defined in MonadState, the concrete implementation of them for "State s a" uses the 'State' constructor. They probably look something like so:
get = State (\s -> (s,s)) put newS = State (\oldS ->( (), newS ))
That still leaves me confused about: put (n+1) AFAICT, with the preceding |n <- get|, this means: put (get+1) and since the get has type, |State Int Int|, and there's not + operator defined on that type (because the following: let get1 = get::(State Int Int) print (evalState get1 99) let get1p1 = get1+1 putStrLn "get1p1=" compiles with error: {---cut here--- GenMonads2Arrows.hs:40:15: No instance for (Num (State Int Int)) arising from a use of `+' at GenMonads2Arrows.hs:40:15-20 Possible fix: add an instance declaration for (Num (State Int Int)) In the expression: get1 + 1 In the definition of `get1p1': get1p1 = get1 + 1 In the expression: do putStr "plusOneCtor=" print (plusOneCtor int1) putStr "plusOne=" print (plusOne int1) }---cut here--- So, looking (again ;) at: http://hackage.haskell.org/packages/archive/mtl/latest/doc/html/Control-Mona... shows: get ::m s where, based on: Instances: MonadState s (State s) from the Control-Monad_state.hmtl#4, m is |State Int| and s is |Int| however, that's just what was used above that wasn't compatible with +1. So, how can get be used in |get+1|? Is there some way to trace what's happening in the tick rhs? Could template haskell be any help here? I can't use ghci because I have to explicity type the get result, and that leads to the above compile error. I'm stuck! Help! [snip]
As long as you aren't writing anything that needs to dig to much into the workings of 'State', you shouldn't have to worry too much about it.
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)) instead of the more obscure: tick = do n <- get put (n+1) return n I figured that understanding how the more obscure definition worked might show me why it was used instead of the simpler definition. However, as noted above, I can't figure out how the more obscure defintion works and I don't even know if the two definitions comput the same results.
I hope I haven't made things more confused ^_^
You've helped. Thanks. -Larry

Hi Larry,
I approached Haskell very recently and I see in your posts many doubts
that I experienced myself, so perhaps I can be of some help by
providing you with the intuition that guided me, rather than with an
in depth explanation of how monadic state works.
On Sat, Nov 1, 2008 at 5:23 PM, Larry Evans
get = State (\s -> (s,s)) put newS = State (\oldS ->( (), newS ))
That still leaves me confused about:
put (n+1)
AFAICT, with the preceding |n <- get|, this means:
put (get+1)
pretty much as with IO, you shouldn't think of get as of a function (or value) representing the value of the state, nor should you think of put as of a function that modifies the state. You should think of get and put (n + 1) as of *actions* that, *when performed*, will read and write the state. In particular put (n + 1) is NOT equivalent to put (get + 1) because "get" here is not the state (of value Int), but it's an action that lets you access the state and n <- get is the way you have to say that you want to perform the get action and bind the value in the state to the name n. The thing that I found really weird in the beginning was that with State the state is never mentioned anywhere! But there is where the intuition "action that reads/writes the state" comes into the game. --luca

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@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

On Sat, Nov 01, 2008 at 11:23:38AM -0500, Larry Evans wrote:
put (n+1) AFAICT, with the preceding |n <- get|, this means:
put (get+1) and since the get has type, |State Int Int|, and there's not + operator defined on that type (because the following:
Others have explained in more detail, let me just state this simply to hopefully clear up the main point of confusion: let x = y and x <- y are *not* the same. In the first case, x is just a name for y, and x and y can be used interchangeably. In the second case, x is bound to *the result of* the action y. So x and y cannot be used interchangeably. -Brent
participants (5)
-
Antoine Latter
-
Brandon S. Allbery KF8NH
-
Brent Yorgey
-
Larry Evans
-
Luca Padovani