[Haskell-beginners] Control.Monad.State: State CTOR unneeded to create a State?

Larry Evans cppljevans at suddenlink.net
Sat Nov 1 12:23:38 EDT 2008

On 10/30/08 21:20, Antoine Latter wrote:
 > On Thu, Oct 30, 2008 at 10:07 PM, Larry Evans 
<cppljevans at suddenlink.net> wrote:
 >> Page:
 >> 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:
 >> 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:
 >> 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---

    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:


  get ::m s
where, based on:

    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

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!

 > 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.


More information about the Beginners mailing list