[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