summaryrefslogtreecommitdiff
path: root/lambda-calcul/haskell
diff options
context:
space:
mode:
authorArnaud Bailly <arnaud@pankzsoft.com>2025-11-05 12:07:48 +0100
committerArnaud Bailly <arnaud@pankzsoft.com>2025-11-05 12:07:48 +0100
commit10feb2dc8ad775a64b6db4d19c76bd6fa38044a8 (patch)
tree823892a835dc7884106c301cd47b83c16ff27356 /lambda-calcul/haskell
parent99e2ce71faa82e7b99574895e0fe24183ba9f6c3 (diff)
downloadlambda-nantes-10feb2dc8ad775a64b6db4d19c76bd6fa38044a8.tar.gz
fix resolution of free variables
Diffstat (limited to 'lambda-calcul/haskell')
-rw-r--r--lambda-calcul/haskell/bool-prog.lisp19
-rw-r--r--lambda-calcul/haskell/src/Minilang/Lambda.hs4
-rw-r--r--lambda-calcul/haskell/src/Minilang/Lambda/DeBruijn.hs6
-rw-r--r--lambda-calcul/haskell/test/Minilang/REPLSpec.hs15
4 files changed, 35 insertions, 9 deletions
diff --git a/lambda-calcul/haskell/bool-prog.lisp b/lambda-calcul/haskell/bool-prog.lisp
new file mode 100644
index 0000000..86fab0a
--- /dev/null
+++ b/lambda-calcul/haskell/bool-prog.lisp
@@ -0,0 +1,19 @@
+(def False (lam (f t) f))
+(def True (lam (f t) t))
+(def Not (lam (b) (b True False)))
+
+(Not True)
+
+(def And (lam (a b) (a False b)))
+(def Or (lam (a b) (a b True)))
+(def If (lam (b x y) (b x y)))
+(def Zero (lam (z s) z))
+(def Succ (lam (n z s) (s n)))
+(def One (Succ Zero))
+(def Two (Succ One))
+(def Three (Succ Two))
+(def IsZero (lam (n) (n True (lam (m) False))))
+
+(Or (IsZero One) (IsZero Two))
+
+(IsZero Zero)
diff --git a/lambda-calcul/haskell/src/Minilang/Lambda.hs b/lambda-calcul/haskell/src/Minilang/Lambda.hs
index 2372578..d223658 100644
--- a/lambda-calcul/haskell/src/Minilang/Lambda.hs
+++ b/lambda-calcul/haskell/src/Minilang/Lambda.hs
@@ -22,8 +22,8 @@ loadProgram language env context exprs =
fmap (\(res, e, c) -> (reverse res, e, c)) result
where
result =
- foldr
- ( \expr acc ->
+ foldl
+ ( \acc expr ->
case acc of
Left typeError -> Left typeError
Right (results, env', context') ->
diff --git a/lambda-calcul/haskell/src/Minilang/Lambda/DeBruijn.hs b/lambda-calcul/haskell/src/Minilang/Lambda/DeBruijn.hs
index de179ad..025fd39 100644
--- a/lambda-calcul/haskell/src/Minilang/Lambda/DeBruijn.hs
+++ b/lambda-calcul/haskell/src/Minilang/Lambda/DeBruijn.hs
@@ -47,14 +47,16 @@ eval (App f a) =
f' -> App f' a
eval term = term
-eval' :: Show ann => Env ann -> DeBruijn ann -> DeBruijn ann
+eval' :: (Show ann, Eq ann) => Env ann -> DeBruijn ann -> DeBruijn ann
eval' env (FV v) = case lookup v env of
Just term -> term
Nothing -> FV v
eval' env (App f a) =
case eval' env f of
Lam _ body -> eval' env (substitute env 0 a body)
- f' -> eval' env $ App f' a
+ f' -> if f' /= f
+ then eval' env $ App f' a
+ else App f' a
eval' _ term = term
substitute :: Env ann -> Int -> DeBruijn ann -> DeBruijn ann -> DeBruijn ann
diff --git a/lambda-calcul/haskell/test/Minilang/REPLSpec.hs b/lambda-calcul/haskell/test/Minilang/REPLSpec.hs
index aa73b69..851706c 100644
--- a/lambda-calcul/haskell/test/Minilang/REPLSpec.hs
+++ b/lambda-calcul/haskell/test/Minilang/REPLSpec.hs
@@ -90,15 +90,20 @@ spec = parallel $
"REPLError \"cannot load file foo in Pure interpreter\""
]
- -- it "can load 'bool-prog.lisp'" $ do
- -- boolProg <- readFile "bool-prog.lisp"
- -- let PurerEnv{outputs} = runProgram (loadProgramInEnv boolProg)
- -- outputs `shouldBe` []
+ it "can load 'bool-prog.lisp'" $ do
+ boolProg <- readFile "bool-prog.lisp"
+ let PurerEnv{outputs} = runProgram (loadProgramInEnv boolProg)
+ outputs `shouldBe` []
it "can load 'bool.lisp'" $ do
boolProg <- readFile "bool.lisp"
let PurerEnv {outputs} = runProgram (loadProgramInEnv boolProg)
- outputs `shouldBe` [Evaluated (Abs ["f", "t"] (Sym "f")) (Lam "f" (Lam "t" (Var "f"))) (TyVar "<?>")]
+ outputs
+ `shouldBe` [ Evaluated
+ (Abs ["f", "t"] (Sym "f"))
+ (Lam "f" (Lam "t" (Var "f")))
+ (TyVar "<?>")
+ ]
around withTempFile $
it "evaluates single MiniLang term read from IO" $ \fileName -> do