实现alpha等价 - Haskell

时间:2015-10-04 21:09:56

标签: haskell

所以让我来定义一些事情:

type Name = String

data Exp = Var Name 
         | App Exp Exp
         | Lam Name Exp
  deriving (Eq,Show,Read)

我想定义alpha-equivalence,即

alpha_eq :: Exp -> Exp -> Bool
-- The terms x and y are not alpha-equivalent, because they are not bound in a lambda abstraction 
alpha_eq (Var x) (Var y) = False
alpha_eq (Lam x e1) (Lam y e2) = False
alpha_eq (App e1 e2) (App e3 e4) = False

例如,Lam "x" (Var "x")Lam "y" (Var "y")都是等效的。然而,Haskell,我既新又可怕。有人能提供一些如何实施alpha_eq的线索吗?我想到的一件事是使用Map Name Int所以在这种情况下我会:

['x' -> 0] ['y' -> 0]

所以在这种情况下Map['x'] == Map['y']。但我再次对Haskell很恐怖。你能不能给我一个如何实现它的线索?

2 个答案:

答案 0 :(得分:8)

是的,使用Map一个正确的想法(虽然考虑键和值类型应该是什么;使用Map Name Int你需要两个额外的参数而不是一个)。你需要将它添加为辅助函数的参数,因为你只要求提供线索,我不会给出完整的实现:

alpha_eq e1 e2 = alpha_eq' e1 e2 env0 where
  env0 = ???
  alpha_eq' (Var x) (Var y) env = ???
  alpha_eq' (Lambda x e1) (Lambda y e2) env = ???
  alpha_eq' (App e1 e2) (App e3 e4) env = ???
  -- you don't want to throw an error in all other cases
  alpha_eq' _ _ env = ???

答案 1 :(得分:4)

您还可以创建单独的函数subst :: Name -> Exp -> Exp -> Exp。然后,alpha_eq Lam-case变为

alpha_eq :: Exp -> Exp -> Bool
...
alpha_eq (Lam x xb) (Lam y yb) = xb `alpha_eq` subst y (Var x) yb
...

Excersise:找出其他alpha_eq案例和subst的实施。