[Haskell-cafe] Simple Interpreter with State Monad

Holger Siegel holgersiegel74 at yahoo.de
Thu Apr 7 15:35:19 UTC 2016

Am Donnerstag, den 07.04.2016, 14:29 +0000 schrieb Jake:
> I'm currently in a graphics class where, in order to provide a
> standard interface to all of our graphics libraries, we have to
> process small scripts that look like this:
> line
> 0 0 0 1 1 1
> circle
> 0 0 10
> scale
> 0 0 3
> save
> pic.png
> I successfully wrote a parser with attoparsec that parses the file
> into a list of Commands. Now I'm trying to process that list to
> produce an IO action, and I thought the State monad would be useful to
> keep track of the persistent state of the shapes to draw and the
> transformations on them.

> I'm confused about how exactly to do this though. What should the type
> of my State be? Right now I have an execute function that is
> execute :: Command -> State ParseState (IO ())
> where ParseState is a tuple of stuff. ParseState also includes an IO
> () because I wanted to be able to create multiple pictures one after
> another, and I couldn't figure out how to access the previous result
> value from State to add on to it in the next one.
> So can anyone offer advice on my specific situation, or maybe a
> simpler example of how to go about writing an interpreter with the
> State monad?

What do you mean by 'persistent state of the shapes'? The canvas itself?

You have an operation that applies a command to a canvas:

  evalCommand :: Canvas -> Command -> Canvas

But you also want to save intermediate results, so the result has to be
an IO action:

  runCommand :: Canvas -> Command -> IO Canvas

You also have an empty initial canvas:

  emptyCanvas :: Canvas

And finally you supply the parsed list of commands:

c :: [Command]

Now you want to calculate a value of type (IO Canvas) from the above:

runAll :: [Command] -> IO Canvas
runAll c = foldM runCommand emptyCanvas c

I don't see how the state monad can make things easier here.

More information about the Haskell-Cafe mailing list