module CC.Term.Raw import CC.Name import CC.Term import Data.DPair import Data.List1 -- Definition ------------------------------------------------------------------ public export data RawTerm : Type where Var : (n : Name) -> RawTerm Abs : (n : Name) -> RawTerm -> RawTerm App : RawTerm -> RawTerm -> RawTerm Let : (n : Name) -> RawTerm -> RawTerm -> RawTerm %name RawTerm t, u -- Error Type ------------------------------------------------------------------ export data NameError : Type -> Type where Ok : ty -> NameError ty Err : List1 Name -> NameError ty export Functor NameError where map f (Ok v) = Ok (f v) map f (Err errs) = Err errs export Applicative NameError where pure = Ok Ok f <*> Ok v = Ok (f v) Ok f <*> Err ys = Err ys Err xs <*> Ok v = Err xs Err xs <*> Err ys = Err (xs ++ ys) export runNameError : NameError ty -> Either (List1 Name) ty runNameError (Ok x) = Right x runNameError (Err xs) = Left xs -- Translation ----------------------------------------------------------------- export lookup : (ctx : Context) -> (n : Name) -> NameError $ Subset Nat (\k => IsVar k n ctx) lookup [<] n = Err (n ::: []) lookup (ctx :< m) n = case decEquiv n m of Yes eq => Ok (Element 0 (Here eq)) No _ => map (\p => Element (S p.fst) (There p.snd)) (lookup ctx n) export translate : (ctx : Context) -> RawTerm -> NameError (Term ctx) translate ctx (Var n) = (\p => Var p.fst n p.snd) <$> lookup ctx n translate ctx (Abs n t) = pure (Abs n) <*> translate (ctx :< n) t translate ctx (App t u) = [| App (translate ctx t) (translate ctx u) |] translate ctx (Let n t u) = pure (Let n) <*> translate ctx t <*> translate (ctx :< n) u