Re: [Haskell-cafe] Very simple parser

I hadn't seen that before, thanks. My code wouldn't be that useful as it depends on some of my datatypes. I don't know some basic things here since I'm so new to Haskell. For example, am I to assume that I need to create my own instance of State and then define get and put for it? Some of the examples seem to just use functions that manipulate a state but do not create a new datatype.
----- Original Message ----
From: Arie Peterson

Gregory Propf wrote: | [...] For example, am I to assume that I need to | create my own instance of State and then define get and put for it? No, there is a 'State s' monad provided (for arbitrary state type 's'), which implements the 'get' and 'put' methods. In other words, 'State s' is an instance of the 'MonadState s' class. This terminology can be really confusing at first. For now, you may forget about the MonadState class. Simply use 'get' & friends and everything will work fine. To get you going, start with the example from the documentation, modified slightly:
tick :: State Int String tick = do n <- get put (n+1) return (show n)
If you want to actually run 'tick', use the 'runState' function:
runTick :: Int -> (String,Int) runTick = runState tick
The argument of 'runTick' is used as initial state. The returned String is the return value, the Int is the final state. Now, put this code in a module and load it in an interpreter (ghci, hugs,...). Unleash 'runTick' on an integer number of your choice, and convince yourself that the result is what you would expect from the definition of 'tick'. Next, try to make some variants of 'tick': replace the return value by something else, or use a list [Int] as state, instead of a single number. Shout if you need more or other help. Kind regards, Arie

On Tuesday 03 July 2007 09:51, Arie Peterson wrote:
No, there is a 'State s' monad provided (for arbitrary state type 's'), which implements the 'get' and 'put' methods. In other words, 'State s' is an instance of the 'MonadState s' class. This terminology can be really confusing at first.
For now, you may forget about the MonadState class. Simply use 'get' & friends and everything will work fine.
This may be a stupid question, but i don't understand how (indeed, if) one can maintain multiple states using the State monad, since 'get' etc. don't seem to require that one specify which particular copy of a State monad one wishes to 'get' from, 'put' to etc.? Does one have to use (say) a tuple or a list to contain all the states, and when one wishes to change only one of those states, pass that entire tuple or list to 'put' with one element changed and the rest unchanged? Alexis.

Alexis Hazell wrote: | This may be a stupid question, but i don't understand how (indeed, if) one | can | maintain multiple states using the State monad, since 'get' etc. don't | seem | to require that one specify which particular copy of a State monad one | wishes | to 'get' from, 'put' to etc.? Does one have to use (say) a tuple or a list | to | contain all the states, and when one wishes to change only one of those | states, pass that entire tuple or list to 'put' with one element changed | and | the rest unchanged? There are (at least) two ways to do this: 1. If the pieces of state are in any way related, I would try to put them together in some data structure. Ideally, this structure is useful beyond the state monad alone. The 'gets' and 'modify' functions from Control.Monad.State can help to keep low overhead. If you use something like "functional references" (see http://www.mail-archive.com/haskell-cafe@haskell.org/msg24704.html), and define helper functions
getR = gets . Data.Ref.select modifyR = modify . Data.Ref.update
, you may deal with state like this:
data S = S { foo :: Foo bar :: Int }
$(deriveRecordRefs ''S)
do foo <- getR fooRef modifyR barRef succ return foo
The syntax can be improved, but it works OK. 2. If the pieces of state are unrelated, and especially if the different states are not always present at the same time, I would stack multiple StateT monad transformers. There was a question about this recently, see http://www.nabble.com/advice:-instantiating-duplicating-modules-t4000935.htm.... Greetings, Arie -- Rules to a drinking game concerning this badge will be forthcoming.

On Thu, Jul 05, 2007 at 12:58:06AM +1000, Alexis Hazell wrote:
On Tuesday 03 July 2007 09:51, Arie Peterson wrote:
No, there is a 'State s' monad provided (for arbitrary state type 's'), which implements the 'get' and 'put' methods. In other words, 'State s' is an instance of the 'MonadState s' class. This terminology can be really confusing at first.
For now, you may forget about the MonadState class. Simply use 'get' & friends and everything will work fine.
This may be a stupid question, but i don't understand how (indeed, if) one can maintain multiple states using the State monad, since 'get' etc. don't seem to require that one specify which particular copy of a State monad one wishes to 'get' from, 'put' to etc.? Does one have to use (say) a tuple or a list to contain all the states, and when one wishes to change only one of those states, pass that entire tuple or list to 'put' with one element changed and the rest unchanged?
Alexis. A value of type 'State t' contains an incapsulated function can be de-encapsulated using runState and when evaluated, performs the actual computation. This function maintains state internally, so for each invocation of this function (such functions from other values of type 'State t') state is preserved separately.
Hope this clarifies your confusion.
participants (4)
-
Alexis Hazell
-
Arie Peterson
-
Gregory Propf
-
Ilya Tsindlekht