[Haskell-cafe] Simple Interpreter with State Monad

Jake jake.waksbaum at gmail.com
Wed Apr 13 14:35:38 UTC 2016


Thanks to everyone for the suggestions, I'm reading up on Monad
transformers and I'll see where that takes me.

Graham, I was also curious why your parsers return SwishStateIO ()? When I
was thinking about the design, it made sense to me to separate the parser
from the interperter, that is my parsers return Command, where Command is
defined like this:

data Command = Line D3Coord D3Coord D3Coord D3Coord D3Coord D3Coord
             | Circle D3Coord D3Coord D3Coord
             | Hermite D3Coord D3Coord D3Coord D3Coord D3Coord D3Coord
D3Coord D3Coord
             | Bezier D3Coord D3Coord D3Coord D3Coord D3Coord D3Coord
D3Coord D3Coord
             | Identity
             | Scale D3Coord D3Coord D3Coord
             | Translate D3Coord D3Coord D3Coord
             | RotateX D3Coord
             | RotateY D3Coord
             | RotateZ D3Coord
             | Apply
             | Display
             | Save FilePath

And then, my interpreter will consume a [Command] and produce some sort of
Monad. What are the advantages of doing it your way?

Thanks,
Jake

On Thu, Apr 7, 2016 at 1:05 PM Graham Klyne <gk at ninebynine.org> wrote:

> 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
> >
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20160413/8d71aebd/attachment.html>


More information about the Haskell-Cafe mailing list