title: Simple interpreter written in Haskell, saves up print output until the end, instead of when it comes across a print statement
body: <p>Below is my attempt at a very simple interpreter which is translated from the Java version of the program described in Chapter 1 of "modern compiler implementation in Java" by Andrew w. Appel, and operates directly upon a tree which represents the language.</p>
  
  <p>Basically, my problem is that it saves up all the output until the end before anything at all is printed. I'm really just looking for advice on how to restructure it so that the "print" statements are printed as they are interpreted.</p>
  
  <pre><code>module Interpreter where
  
  --------------------------------------------------------------------
  
  type Id         =   [Char]
  type Output     =   [Char]
  type Value      =   Int
  type Table      =   [(Id, Value)]
  
  data Stm        =   CompoundStm Stm Stm |
                      AssignStm Id Exp |
                      PrintStm ExpList deriving Show
  
  data Exp        =   IdExp Id |
                      NumExp Value |
                      OpExp Exp Op Exp |
                      EseqExp Stm Exp deriving Show
  
  data ExpList    =   PairExpList Exp ExpList |
                      LastExpList Exp deriving Show
  
  data Op         =   Plus | Minus | Times | Div deriving Show
  
  --------------------------------------------------------------------
  
  example ::  Stm
  example =   CompoundStm (AssignStm "a" (OpExp (NumExp 5) Plus (NumExp 3))) 
              (CompoundStm (AssignStm "b" (EseqExp (PrintStm (PairExpList (IdExp "a")
               (LastExpList (OpExp (IdExp "a") Minus (NumExp 1))))) (OpExp (NumExp 10) Times
                (IdExp "a")))) (PrintStm (LastExpList (IdExp "b"))))
  
  --------------------------------------------------------------------
  
  tableUpdate                             ::  Table -&gt; Id -&gt; Value -&gt; Table
  tableUpdate t i v                       =   (i,v):t
  
  tableLookup                             ::  Table -&gt; Id -&gt; Value
  tableLookup ((x,v):t) i | x == i        =   v
  tableLookup ((x,v):t) i | x /= i        =   tableLookup t i
  
  --------------------------------------------------------------------
  
  execute                                 ::  Stm -&gt; IO()
  execute s                               =   putStr ((\(o,_)-&gt;o) (interpStm s ("",[])))
  
  interpStm                               ::  Stm -&gt; (Output, Table) -&gt; (Output, Table)
  interpStm (CompoundStm l r) ot          =   interpStm r (interpStm l ot)
  interpStm (PrintStm el) (o,t)           =   (interpExpList el o t)
  interpStm (AssignStm i e) (o,t)         =   f i (interpExp e (o,t))
          where
              f i (v,o,t)                 =   (o, tableUpdate t i v)
  
  interpExp                               ::  Exp -&gt; (Output, Table) -&gt; (Value, Output, Table)
  interpExp (IdExp i) (o,t)               =   (tableLookup t i, o, t)
  interpExp (NumExp v) (o,t)              =   (v, o, t)
  interpExp (EseqExp s e) ot              =   interpExp e (interpStm s ot)
  interpExp (OpExp l op r) (o,t)          =   f (interpExp l (o,t)) op r
          where
              f (v,o,t) op r              =   g v op (interpExp r (o,t))
              g v1 Plus (v2,o,t)          =   (v1 + v2, o, t)
              g v1 Minus (v2,o,t)         =   (v1 - v2, o, t)
              g v1 Times (v2,o,t)         =   (v1 * v2, o, t)
              g v1 Div (v2,o,t)           =   (v1 `div` v2, o, t)
  
  interpExpList                           ::  ExpList -&gt; Output -&gt; Table -&gt; (Output, Table)
  interpExpList (LastExpList e) o t       =   f (interpExp e (o,t))       
          where
              f (v, o, t)                 =   (o ++ (show v) ++ "\n", t)
  interpExpList (PairExpList e el) o t    =   f (interpExp e (o,t))
          where
              f (v, o, t)                 =   interpExpList el (o ++ (show v) ++ " ") t
  </code></pre>