Mercurial > hg > Members > atton > tapl
view untyped/Untyped.hs @ 9:4bfeb679ef15
Add eval1 in Untyped
author | atton |
---|---|
date | Tue, 01 Nov 2016 04:53:18 +0000 |
parents | 5fa32bb75df6 |
children |
line wrap: on
line source
module Untyped where import Data.Either import Data.Functor type Index = Int type ContextSize = Int type Name = String data Binding = NameBind deriving Show type Context = [(Name, Binding)] data Term = TmVar Index ContextSize | TmAbs String Term | TmApp Term Term deriving Show -- my implementation index2name :: Context -> Index -> String index2name ctx i = fst $ ctx !! i pickFreshName :: Context -> Name -> (Context, Name) pickFreshName ctx n = (((freshName, NameBind) : ctx), freshName) where freshName = head . dropWhile (flip elem $ map fst ctx) $ iterate (++ "'") n -- from book showTerm :: Context -> Term -> String showTerm ctx (TmAbs x t) = let (ctx', x') = pickFreshName ctx x in "(lambda " ++ x' ++ ". " ++ (showTerm ctx' t) ++ ")" showTerm ctx (TmApp t1 t2) = "(" ++ (showTerm ctx t1) ++ " " ++ (showTerm ctx t2) ++ ")" showTerm ctx (TmVar i n) | length ctx == n = index2name ctx i | otherwise = "[bad index]" termShift :: Int -> Term -> Term termShift d t = walk 0 t where walk c (TmVar x n) | x >= c = TmVar (x+d) (n+d) | otherwise = TmVar x (n+d) walk c (TmAbs x t1) = TmAbs x (walk (c+1) t1) walk c (TmApp t1 t2) = TmApp (walk c t1) (walk c t2) termSubst :: Index -> Term -> Term -> Term termSubst j s t = walk 0 t where walk c (TmVar x n) | x == (j+c) = termShift c s | otherwise = TmVar x n walk c (TmAbs x t1) = TmAbs x (walk (c+1) t1) walk c (TmApp t1 t2) = TmApp (walk c t1) (walk c t2) termSubstTop s t = termShift (-1) (termSubst 0 (termShift 1 s) t) isVal :: Context -> Term -> Bool isVal ctx (TmAbs _ _) = True isval _ _ = False eval1 :: Context -> Term -> Either String Term eval1 ctx (TmApp (TmAbs x t12) v2) | isVal ctx v2 = return $ termSubstTop v2 t12 | otherwise = Left $ show v2 ++ " is not variable." eval1 ctx (TmApp t1 t2) | isVal ctx t1 = eval1 ctx t2 >>= (\t -> return $ TmApp t1 t) | otherwise = eval1 ctx t1 >>= (\t -> return $ TmApp t t2) eval1 _ _ = Left "No Rule Applies" -- x sampleContext1 = [("x", NameBind)] sampleTerm1 = TmVar 0 1 -- \y -> y sampleContext2 = [] sampleTerm2 = TmAbs "y" (TmVar 0 1) -- (\x -> x) (\x -> x x) == \x' -> x' x' sampleContext3 = [] sampleTerm3 = (TmApp (TmAbs "x" (TmVar 0 1)) (TmAbs "x" (TmApp (TmVar 0 1) (TmVar 0 1)))) -- (\y -> (\x -> y)) (\x -> x x) sampleContext4 = [] sampleTerm3 = (TmApp (TmAbs "x" (TmVar 0 1)) (TmAbs "x" (TmApp (TmVar 0 1) (TmVar 0 1)))) sampleTerm4 = TmApp (TmAbs "y" (TmAbs "x" (TmVar 1 2))) (TmAbs "x" (TmApp (TmVar 0 1) (TmVar 0 1)))