lambda-calculator-0.5.0: test/Language/Lambda/EvalSpec.hs
module Language.Lambda.EvalSpec where
import Test.Hspec
import Language.Lambda
import Language.Lambda.Eval
import Language.Lambda.Expression
spec :: Spec
spec = do
describe "evalExpr" $ do
let evalExpr' = evalExpr uniques
it "beta reduces" $ do
let expr = App (Abs "x" (Var "x")) (Var "z")
evalExpr' expr `shouldBe` Var "z"
it "reduces multiple applications" $ do
let expr = App (App (Abs "f" (Abs "x" (App (Var "f") (Var "x")))) (Var "g")) (Var "y")
evalExpr' expr `shouldBe` App (Var "g") (Var "y")
it "reduces inner redexes" $ do
let expr = Abs "x" (App (Abs "y" (Var "y")) (Var "x"))
evalExpr' expr `shouldBe` Abs "x" (Var "x")
it "reduces with name captures" $ do
let expr = App (Abs "f" (Abs "x" (App (Var "f") (Var "x"))))
(Abs "f" (Var "x"))
evalExpr' expr `shouldBe` Abs "z" (Var "x")
describe "betaReduce" $ do
let betaReduce' = betaReduce []
it "reduces simple applications" $ do
let e1 = Abs "x" (Var "x")
e2 = (Var "y")
betaReduce' e1 e2 `shouldBe` Var "y"
it "reduces nested abstractions" $ do
let e1 = Abs "x" (Abs "y" (Var "x"))
e2 = Var "z"
betaReduce' e1 e2 `shouldBe` Abs "y" (Var "z")
it "reduces inner applications" $ do
let e1 = Abs "f" (App (Var "f") (Var "x"))
e2 = Var "g"
betaReduce' e1 e2 `shouldBe` App (Var "g") (Var "x")
it "does not reduce unreducible expression" $ do
let e1 = Var "x"
e2 = Var "y"
betaReduce' e1 e2 `shouldBe` App (Var "x") (Var "y")
it "does not reduce irreducible chained applications" $ do
let e1 = App (Var "x") (Var "y")
e2 = Var "z"
betaReduce' e1 e2 `shouldBe` App (App (Var "x") (Var "y")) (Var "z")
it "does not sub shadowed bindings" $ do
let e1 = Abs "x" (Abs "x" (Var "x"))
e2 = Var "z"
betaReduce' e1 e2 `shouldBe` Abs "x" (Var "x")
describe "alphaConvert" $ do
it "alpha converts simple expressions" $ do
let freeVars = ["x"]
expr = Abs "x" (Var "x")
uniques = ["y"]
alphaConvert uniques freeVars expr `shouldBe` Abs "y" (Var "y")
it "avoids captures" $ do
let freeVars = ["x"]
expr = Abs "x" (Var "x")
uniques = ["x", "y"]
alphaConvert uniques freeVars expr `shouldBe` Abs "y" (Var "y")
describe "freeVarsOf" $ do
it "Returns simple vars" $ do
freeVarsOf (Var "x") `shouldBe` ["x"]
it "Does not return bound vars" $ do
freeVarsOf (Abs "x" (Var "x")) `shouldBe` []
it "Returns nested simple vars" $ do
freeVarsOf (Abs "x" (Var "y")) `shouldBe` ["y"]
it "Returns applied simple vars" $ do
freeVarsOf (App (Var "x") (Var "y")) `shouldBe` ["x", "y"]