{-# LINE 3 "small/Eval.as" #-}
module Main where
{-# LINE 3 "small/Eval.as" #-}
import Maybe (fromJust)
{-# LINE 4 "small/Eval.as" #-}
import Arrow
 
{-# LINE 6 "small/Eval.as" #-}
type Id = String
 
{-# LINE 7 "small/Eval.as" #-}
data Val a = Num Int
	   | Bl Bool
	   | Fun (a (Val a) (Val a))
 
{-# LINE 8 "small/Eval.as" #-}
data Exp = Var Id
	 | Add Exp Exp
	 | If Exp Exp Exp
	 | Lam Id Exp
	 | App Exp Exp
 
{-# LINE 10 "small/Eval.as" #-}
eval ::
     (ArrowChoice a, ArrowApply a) => Exp -> a [(Id, Val a)] (Val a)
{-# LINE 11 "small/Eval.as" #-}
eval (Var s) = (arr (\ env -> fromJust (lookup s env)))
{-# LINE 13 "small/Eval.as" #-}
eval (Add e1 e2)
  = (arr (\ env -> (env, env)) >>>
       (first (eval e1) >>>
	  arr (\ (vP_0@ ~(Num u), env) -> (env, (u, vP_0))))
	 >>>
	 (first (eval e2) >>>
	    arr (\ (vP_1@ ~(Num v), (u, vP_0@ ~(Num u))) -> Num (u + v))))
{-# LINE 17 "small/Eval.as" #-}
eval (If e1 e2 e3)
  = (arr (\ env -> (env, env)) >>>
       (first (eval e1) >>>
	  arr (\ (vP_0@ ~(Bl b), env) -> if b then Left env else Right env))
	 >>> (eval e2 ||| eval e3))
{-# LINE 21 "small/Eval.as" #-}
eval (Lam x e)
  = (arr (\ env -> Fun ((arr (\ v -> (x, v) : env) >>> eval e))))
{-# LINE 23 "small/Eval.as" #-}
eval (App e1 e2)
  = (arr (\ env -> (env, env)) >>>
       (first (eval e1) >>>
	  arr (\ (vP_0@ ~(Fun f), env) -> (env, (f, vP_0))))
	 >>>
	 (first (eval e2) >>> arr (\ (v, (f, vP_0@ ~(Fun f))) -> (f, v)))
	   >>> app)
{-# LINE 30 "small/Eval.as" #-}
i = Lam "x" (Var "x")
{-# LINE 31 "small/Eval.as" #-}
k = Lam "x" (Lam "y" (Var "x"))
{-# LINE 32 "small/Eval.as" #-}
double = Lam "x" (Add (Var "x") (Var "x"))
{-# LINE 34 "small/Eval.as" #-}
t = n
  where {-# LINE 35 "small/Eval.as" #-}
	Num n
	  = eval
	      (If (Var "b") (App (App k (App double (Var "x"))) (Var "x"))
		 (Add (Var "x") (Add (Var "x") (Var "x"))))
	      [("b", Bl True), ("x", Num 5)]
