[Haskell-cafe] Simple Interpreter with State Monad

Graham Klyne gk at ninebynine.org
Thu Apr 7 17:05:15 UTC 2016


On 07/04/2016 15:29, Jake wrote:> 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:
   [...]

I did something like this for my Swish system, some time ago.

Several others adapted the software, and most recently Doug Burke put the code 
in BitBucket.

Relevant modules are

"Scrips.hs" - originally a "parsec" based parser, but now something else, parses 
script source and returns a "SwishStateIO" monad.

- 
https://bitbucket.org/doug_burke/swish/src/8f72b52f02fb540e8e1c26caa5036920a9ff31da/src/Swish/Script.hs?at=default&fileviewer=file-view-default

"Monad.hs" - defines the "SwishStateIO" monad, and defines implementations of 
the primitive functions of the scripting language.  It's a long time since I 
looked at this, but I think a key part of the definition is:

     type SwishStateIO a = StateT SwishState IO a

which (if I get this right) wraps the basic state and associated transformation 
functions in an IO monad.

- 
https://bitbucket.org/doug_burke/swish/src/8f72b52f02fb540e8e1c26caa5036920a9ff31da/src/Swish/Monad.hs?at=default&fileviewer=file-view-default

The "compiled" script (SwishStateIO value) is run by applying it to an initial 
state; the module that pulls it all together is:

- 
https://bitbucket.org/doug_burke/swish/src/8f72b52f02fb540e8e1c26caa5036920a9ff31da/src/Swish.hs?at=default&fileviewer=file-view-default

...

I'm not sure if any of this makes any sense, but the key idea for me, way back 
when, was the capability to compile a script directly to a monadic function that 
could then be executed by function application to an initial state (in this 
case, using execStateT).

#g
--


On 07/04/2016 15:29, Jake wrote:
> 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?
>
> Thanks,
> Jake
>
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>


More information about the Haskell-Cafe mailing list