从this Haskell Cafe的帖子中,借用一些代码示例来自jyp,我们可以在Haskell中构建一个简单的PHOAS评估器,如下所示:
这个实现允许我们创建、规范化和字符串化λ演算的项。问题是,
{-# LANGUAGE GADTs #-}
{-# LANGUAGE RankNTypes #-}
import Data.Char
data Term v t where
Var :: v t -> Term v t
App :: Term v (a -> b) -> Term v a -> Term v b
Lam :: (v a -> Term v b) -> Term v (a -> b)
data Exp t = Exp (forall v. Term v t)
-- An evaluator
eval :: Exp t -> t
eval (Exp e) = evalP e
data Id a = Id {fromId :: a}
evalP :: Term Id t -> t
evalP (Var (Id a)) = a
evalP (App e1 e2) = evalP e1 $ evalP e2
evalP (Lam f) = \a -> evalP (f (Id a))
data K t a = K t
showTermGo :: Int -> Term (K Int) t -> String
showTermGo _ (Var (K i)) = "x" ++ show i
showTermGo d (App f x) = "(" ++ showTermGo d f ++ " " ++ showTermGo d x ++ ")"
showTermGo d (Lam a) = "@x" ++ show d ++ " " ++ showTermGo (d+1) (a (K d))
showTerm :: Exp t -> String
showTerm (Exp e) = showTermGo 0 e
这个实现允许我们创建、规范化和字符串化λ演算的项。问题是,
eval
的类型是Exp t -> t
而不是Exp t -> Exp t
。因此,我不清楚如何将一个项求值为规范形式,然后将其字符串化。在PHOAS中是否可能实现这个功能?
class Norm t where { unquote :: Term t -> t; quote :: t -> Term t }; instance (Norm a, Norm b) => Norm (a -> b) where { unquote f = \x -> unquote (App f (quote x)); quote f = Lam (\x -> quote (f (unquote (Var x)))) }
。但我并不立即看到如何处理你的多态Term v t
和Exp t
。 - undefined