Last active
May 28, 2018 19:42
-
-
Save polux/1d47877845c7fee109b9f3e056f3e90d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Copyright 2018 Google LLC. | |
-- SPDX-License-Identifier: Apache-2.0 | |
{-# LANGUAGE FlexibleContexts #-} | |
import Control.Applicative | |
import Control.Monad.Writer | |
data Expr = Lit Int | Plus Expr Expr | Times Expr Expr | |
deriving (Eq, Show) | |
ev ev e = ev' e | |
where ev' (Lit i) = pure i | |
ev' (Plus a b) = liftA2 (+) (ev a) (ev b) | |
ev' (Times a b) = liftA2 (*) (ev a) (ev b) | |
evTell ev0 ev e = do | |
v <- ev0 ev e | |
tell [(e, v)] | |
return v | |
eval e = execWriter (fix (evTell ev) e) | |
main = mapM_ print (eval test) | |
where test = (Lit 1 `Plus` Lit 2) `Times` (Lit 3 `Plus` Lit 4) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is nice, but is there a way to stuff the result alongside the AST, as in
(Times (Plus (Lit 1, 1) (Lit 2, 2), 3) (Plus (Lit 3, 3) (Lit 4, 4), 7),21) ?
IMO it is shorter and context is maintained.