所以让我来定义一些事情:
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很恐怖。你能不能给我一个如何实现它的线索?
答案 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
的实施。