Skip to content

Instantly share code, notes, and snippets.

@ice1000
Forked from lunalunaa/untyped-lambda.hs
Last active December 15, 2019 05:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ice1000/a850a12149c552c9a85ec242b86f9099 to your computer and use it in GitHub Desktop.
Save ice1000/a850a12149c552c9a85ec242b86f9099 to your computer and use it in GitHub Desktop.
{-# LANGUAGE LambdaCase #-}
data Term
= TmVar Integer
| TmAbs String Term
| TmApp Term Term
deriving (Show, Eq)
termShift :: Integer -> Term -> Term
termShift d = walk 0
where
walk :: Integer -> Term -> Term
walk c = \case
TmVar x -> if x > c then TmVar (x + d) else TmVar x
TmAbs x t1 -> TmAbs x (walk (succ c) t1)
TmApp t1 t2 -> TmApp (walk c t1) (walk c t2)
termSubst :: Integer -> Term -> Term -> Term
termSubst j s = walk 0
where
walk :: Integer -> Term -> Term
walk c = \case
TmVar x -> if x == j + c then termShift c s else TmVar x
TmAbs x t1 -> TmAbs x (walk (succ c) t1)
TmApp t1 t2 -> TmApp (walk c t1) (walk c t2)
termSubstTop :: Term -> Term -> Term
termSubstTop s t = termShift (-1) $ termSubst 0 (termShift 1 s) t
isval :: Term -> Bool
isval t = case t of
TmAbs _ _ -> True
_ -> False
eval :: Term -> Term
eval = \case
TmApp t1 t2 -> case eval t1 of
TmAbs x t1' -> let v2' = eval t2 in
if isval v2'
then eval (termSubstTop v2' t1')
else TmApp t1' t2
t1'' -> TmApp t1'' t2 -- or t
t -> t
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment