primitive2 :: (b -> GMState -> GMState) -- boxing function
                -> (Addr -> GMState -> a) -- unboxing function
                -> (a -> a -> b) -- operator
                -> (GMState -> GMState) -- state transition
primitive2 box unbox op state
    = box result state'
    where 
        result = (op (unbox a0 state) (unbox a1 state))
        (a0:a1:as) = getStack state
        state' = (putStack as state)
primitive2 :: (b -> GMState -> GMState) -- boxing function
                -> (Addr -> GMState -> a) -- unboxing function
                -> (a -> a -> b) -- operator
                -> (GMState -> GMState)
primitive2 box unbox op state
    = box result state'
    where 
        result = (op (unbox a0 state) (unbox a1 state))
        (a0:a1:as) = getStack state
        state' = (putStack as state)
primitive2 box unbox op state
    = box result state'
    where 
        result = (op (unbox a0 state) (unbox a1 state))
        (a0:a1:as) = getStack state
        state' = (putStack as state)