[Haskell-cafe] Very simple parser

Arie Peterson ariep at xs4all.nl
Wed Jul 4 13:33:23 EDT 2007


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


Greetings,

Arie

-- 

Rules to a drinking game concerning this badge will be forthcoming.




More information about the Haskell-Cafe mailing list