[Haskell-cafe] Minim interpreter

Mark Wassell mwassell at bigpond.net.au
Fri Jul 20 18:18:51 EDT 2007


Hugh Perkins wrote:
> That works just fine as long as the only thing eval has to cope with 
> is print statements (so eval has type IO ()), but I'm guessing the 
> clean solution is to thread a Map.Map through that somehow?
>
You could do that but your code starts to become messy and you'll hit 
other limitations. The standard approach to this problem is to use a 
State monad. Since you are already using one monad, IO, you can can 
stack the monads using Monad transformers which makes them both 
available (although you will need to use liftIO, see below)

import Control.Monad
import Control.Monad.State
import Data.Map

type Env = Map String String
type InterpM = StateT Env IO 

eval :: a -> InterpM t

instance Eval Print where
   eval (Print value) = liftIO $ putStrLn value

You access and store the state using get and put. For example:

eval (Variable s) = do
                                    s <- get
                                    lookup the value and return it.

There is a paper on using Monads with interpreters 
(http://web.cecs.pdx.edu/~mpj/pubs/modinterp.html) and an example 
described at http://www.haskell.org/haskellwiki/Libraries_and_tools/HJS.

Mark


More information about the Haskell-Cafe mailing list