
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.