diff options
| author | Arnaud Bailly <arnaud@pankzsoft.com> | 2025-10-13 09:27:07 +0200 |
|---|---|---|
| committer | Arnaud Bailly <arnaud@pankzsoft.com> | 2025-10-13 09:27:07 +0200 |
| commit | 3a67e69bfe9492d2a2fc5e4b07cc8c909a346064 (patch) | |
| tree | 8b4b0281dffe166f5c8495b1a5b892c1f8285870 /lambda-calcul/haskell/test/Minilang/Lambda/EvalSpec.hs | |
| parent | 21befc8c8ab2e91632f5341b4fa9425cf3c815ff (diff) | |
| download | lambda-nantes-3a67e69bfe9492d2a2fc5e4b07cc8c909a346064.tar.gz | |
add minimal evaluator and type inference
Diffstat (limited to 'lambda-calcul/haskell/test/Minilang/Lambda/EvalSpec.hs')
| -rw-r--r-- | lambda-calcul/haskell/test/Minilang/Lambda/EvalSpec.hs | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/lambda-calcul/haskell/test/Minilang/Lambda/EvalSpec.hs b/lambda-calcul/haskell/test/Minilang/Lambda/EvalSpec.hs new file mode 100644 index 0000000..df933a4 --- /dev/null +++ b/lambda-calcul/haskell/test/Minilang/Lambda/EvalSpec.hs @@ -0,0 +1,40 @@ +module Minilang.Lambda.EvalSpec (spec) where + +import Control.Concurrent (threadDelay) +import Control.Concurrent.Async (race_) +import Minilang.Lambda.Eval (Term (..), eval, evalNeed) +import Test.Hspec (Spec, describe, it, shouldBe) + +spec :: Spec +spec = do + let fix = Lam "x" (App (Var "x") (Var "x")) + let omega = App fix fix + let term = App (App (Lam "x" (Lam "y" (Var "y"))) omega) (Var "z") + + describe "call-by-value eval" $ do + it "evaluates 'x' as itself" $ do + let term = Var "x" + eval term [] `shouldBe` Var "x" + it "evaluates '((λ x. x) y)' as 'y'" $ do + let term = App (Lam "x" (Var "x")) (Var "y") + eval term [] `shouldBe` Var "y" + it "evaluates '((λ x y. y) y z t)' as '(z t)'" $ do + let snd' = Lam "x" (Lam "y" (Var "y")) + let term = App (App (App snd' (Var "y")) (Var "z")) (Var "t") + eval term [] `shouldBe` App (Var "z") (Var "t") + it "diverges on evaluating argument bound to ω" $ + shouldDiverge $ eval term [] + + describe "call-by-need eval" $ do + it "evaluates 'x' as itself" $ do + evalNeed (Var "x") [] `shouldBe` Var "x" + it "evaluates '(λ x y . y) ⊥ z' as 'z'" $ do + evalNeed term [] `shouldBe` Var "z" + it "diverges on evaluating ω" $ + shouldDiverge $ evalNeed omega [] + +shouldDiverge :: Term -> IO () +shouldDiverge t = + race_ + (t `seq` fail "Did not diverge") + (threadDelay 1000000) |
