[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:
 >>
 >>  
http://hackage.haskell.org/packages/archive/mtl/latest/doc/html/Control-Monad-State.html#2
 >>
 >> 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-Monad-State.html#4
 >>
 >> 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-Monad-State.html#1
 >>
 >> 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-Monad-State.html#4
 
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






More information about the Beginners mailing list