@@ -3,18 +3,50 @@ module Language.Lambda.Eval where
3
3
import Data.List
4
4
import Data.Maybe
5
5
6
+ import qualified Data.Map as Map
7
+
6
8
import Language.Lambda.Expression
7
9
8
- evalExpr :: Eq n => [n ] -> LambdaExpr n -> LambdaExpr n
9
- evalExpr uniqs (Abs name expr) = Abs name . evalExpr uniqs $ expr
10
- evalExpr _ expr@ (Var _) = expr
11
- evalExpr uniqs (App e1 e2) = betaReduce uniqs (evalExpr uniqs e1)
12
- (evalExpr uniqs e2)
10
+ -- | Evaluate an expression
11
+ evalExpr :: (Eq n , Ord n )
12
+ => Map. Map n (LambdaExpr n ) -- ^ globals
13
+ -> [n ] -- ^ unique supply
14
+ -> LambdaExpr n -- ^ the expression to evaluate
15
+ -> (LambdaExpr n , Map. Map n (LambdaExpr n ))
16
+ evalExpr globals uniqs (Let name expr)
17
+ = (Let name expr', Map. insert name expr' globals)
18
+ where expr' = evalExpr' uniqs (subGlobals globals expr)
19
+ evalExpr globals uniqs expr = (evalExpr' uniqs expr', globals)
20
+ where expr' = subGlobals globals expr
13
21
14
- betaReduce :: Eq n => [n ] -> LambdaExpr n -> LambdaExpr n -> LambdaExpr n
15
- betaReduce uniqs (App e1 e1') e2 = App (betaReduce uniqs e1 e1') e2
22
+ subGlobals :: (Eq n , Ord n )
23
+ => Map. Map n (LambdaExpr n ) -- ^ globals
24
+ -> LambdaExpr n -- ^ the expression
25
+ -> LambdaExpr n
26
+ subGlobals g e@ (Var x) = Map. findWithDefault e x g
27
+ subGlobals g (App e1 e2) = App (subGlobals g e1) (subGlobals g e2)
28
+ subGlobals g (Abs n expr) = Abs n (subGlobals g expr)
29
+ subGlobals _ expr = expr
30
+
31
+ -- | Evaluate an expression; does not support `let`
32
+ evalExpr' :: Eq n
33
+ => [n ] -- ^ unique supply
34
+ -> LambdaExpr n -- ^ the expression to evaluate
35
+ -> LambdaExpr n
36
+ evalExpr' _ expr@ (Var _) = expr
37
+ evalExpr' uniqs (Abs name expr) = Abs name . evalExpr' uniqs $ expr
38
+ evalExpr' uniqs (Let name expr) = Let name . evalExpr' uniqs $ expr
39
+ evalExpr' uniqs (App e1 e2) = betaReduce uniqs (evalExpr' uniqs e1)
40
+ (evalExpr' uniqs e2)
41
+
42
+ betaReduce :: Eq n
43
+ => [n ]
44
+ -> LambdaExpr n
45
+ -> LambdaExpr n
46
+ -> LambdaExpr n
16
47
betaReduce _ expr@ (Var _) e2 = App expr e2
17
- betaReduce uniqs (Abs n e1) e2 = evalExpr uniqs . sub n e1' $ e2
48
+ betaReduce uniqs (App e1 e1') e2 = App (betaReduce uniqs e1 e1') e2
49
+ betaReduce uniqs (Abs n e1) e2 = evalExpr' uniqs . sub n e1' $ e2
18
50
where fvs = freeVarsOf e2
19
51
e1' = alphaConvert uniqs fvs e1
20
52
0 commit comments