[Haskell-beginners] Making a generic interpreter

Erik Helin erik.helin at gmail.com
Fri May 6 09:01:35 CEST 2011


Hi,

I have made the following (very small and basic) interpter:

data Code = PUSH Integer
                 | ADD
                 | BRANCH [Code] [Code]
                 | CMP
                 deriving (Show)

data StackElement = StackInteger Integer
                              | StackBool Bool
                              deriving (Show)
type Stack = [StackElement]

eval :: [Code] -> Stack -> Stack
eval [] s = s
eval (PUSH n:t) s =  eval t (StackInteger n:s)
eval (ADD:t) (StackInteger x:StackInteger y:s) = eval t (StackInteger (x + y):s)
eval (CMP:t) (StackInteger x:StackInteger y:s) = eval t (StackBool (x == y):s)
eval (BRANCH c1 c2:t) (StackBool cond:s) = if cond then eval (c1 ++ t) s

      else eval (c2 ++ t) s

Now, I would like to change StackElement to be able to work with any
types, that is:

data StackElement a b = StackInteger a
                                   | StackInteger b
                                   deriving (Show)

How would I make this change?

I thought about using typeclasses, but since type a and type b in
StackElement a b clearly are related (the == operation on type a must
result in type b), I need to use multi-parameter type classes (and
maybe also functional dependecies?).

I also thought about introducing a new type Operation:

data Operation a b = Operation { cmp :: a -> a -> b, add :: a -> a ->
a, (more required functions) }

Is any of these solutions the preferred one, or is there another
solution that I don't know of (this is very likely, I'm completely new
to Haskell)?

Thanks for taking your time and reading this lengthy post,
Erik



More information about the Beginners mailing list