
-- evaluation contexts, parameterized by rule to apply ctxt rule e = rule e `mplus` left (ctxt rule) e `mplus` right (ctxt rule) e
left act e = do { (Plus l r) <- return e; lv <- act l; return (Plus lv r) } right act e = do { (Plus lv@(Val _) r) <- return e; rv <- act r; return (Plus lv rv) }
actually, for the common case of reduction in context (contexts being preserved unchanged), we can build contexts from context constructors corresponding to the data constructors. moving the common plumbing into the context constructors makes the context specification itself a lot clearer (a transliteration of the formal specification:-): -- context constructors val fi e = do { Val i <- return e; return (Val (fi i)) } plus cl cr e = do { Plus l r <- return e; l' <- cl l; r' <- cr r; return (Plus l' r') } expr e = return e (a .|. b) e = a e `mplus` b e -- evaluation contexts, parameterized by rule to apply, abstract style ctxt' hole = hole .|. plus (ctxt' hole) expr .|. plus (val id) (ctxt' hole) Claus