简体   繁体   English

编写递归函数来重命名 lambda 演算中的项

[英]Writing a recursive function for renaming terms in lambda calculus

I've made an attempt at writing a function that will rename variable names in a Lambda calculus term.我尝试编写一个函数,该函数将重命名 Lambda 演算术语中的变量名称。 The renaming operation is M[y/x] (M with x renamed to y).重命名操作是 M[y/x](M 将 x 重命名为 y)。

The problem lies, in these lines of code, | z == x = y问题在于,在这些代码行中, | z == x = y | z == x = y , where newN = rename(n) , where newZ1 = rename(newZ1) and newZ2 = rename(newZ2) . | z == x = ywhere newN = rename(n)where newZ1 = rename(newZ1)newZ2 = rename(newZ2)

| z == x = y | z == x = y comes up with a type error Expected type: Term Actual type: Var . | z == x = y出现类型错误Expected type: Term Actual type: Var Please can you help me to understand why I get this error?请你能帮我理解为什么我会收到这个错误吗?

The other three errors come from when I attempt to recursively call the rename function.其他三个错误来自我尝试递归调用重命名函数时。 I get the error • Probable cause: 'rename' is applied to too few arguments .我收到错误• Probable cause: 'rename' is applied to too few arguments When I was writing this I thought that it would rename the Variable to according to the case which was set for a Variable.当我写这篇文章时,我认为它会根据为变量设置的大小写来重命名变量。 How do I do this correctly, cheers.我如何正确地做到这一点,欢呼。

type Var = String

data Term =
    Variable Var
  | Lambda   Var  Term
  | Apply    Term Term
--  deriving Show

instance Show Term where
  show = pretty

example :: Term
example = Lambda "a" (Lambda "x" (Apply (Apply (Lambda "y" (Variable "a")) (Variable "x")) (Variable "b")))


pretty :: Term -> String
pretty = f 0
    where
      f i (Variable x) = x
      f i (Lambda x m) = if i /= 0 then "(" ++ s ++ ")" else s where s = "\\" ++ x ++ ". " ++ f 0 m 
      f i (Apply  n m) = if i == 2 then "(" ++ s ++ ")" else s where s = f 1 n ++ " " ++ f 2 m

rename :: Var -> Var -> Term -> Term
rename x y (Variable z)     
    | z == x    = y
    | otherwise = (Variable z)

rename x y (Lambda z n)
    | z == x    = (Lambda z n)
    | otherwise = (Lambda z newN)
                  where newN = rename(n)

rename x y (Apply  n m) = (Apply newZ1 newZ2)
    where newZ1 = rename(newZ1)
          newZ2 = rename(newZ2)

The reasons for the errors are exactly as the messages say.错误的原因与消息所说的完全一样。 I'll go through them, after quoting the whole of the faulty definition:在引用整个错误定义后,我将仔细阅读它们:

rename :: Var -> Var -> Term -> Term
rename x y (Variable z)     
    | z == x    = y
    | otherwise = (Variable z)

rename x y (Lambda z n)
    | z == x    = (Lambda z n)
    | otherwise = (Lambda z newN)
                  where newN = rename(n)

rename x y (Apply  n m) = (Apply newZ1 newZ2)
    where newZ1 = rename(newZ1)
          newZ2 = rename(newZ2)

The first error, as you report, is type error Expected type: Term Actual type: Var , on the line | z == x = y第一个错误,正如你所报告的,是type error Expected type: Term Actual type: Var ,就行| z == x = y | z == x = y . | z == x = y

This is entirely due to the return value in that case, y , which is of type Var .这完全是由于这种情况下的返回值yVar类型。 Yet your signature says the return value must have type Term .然而你的签名说返回值必须是Term类型。 This can be fixed by replacing y with Variable y , exactly as you have done with z on the following line.这可以通过用Variable y替换y来解决,正如您在下一行中对z所做的那样。

As for the other ones, again GHC's suggestion seems to me to be spot on: you haven't applied rename to enough arguments when making your recursive calls.至于其他的,在我看来 GHC 的建议再次正确:在进行递归调用时,您没有对足够的参数应用rename rename has type Var -> Var -> Term -> Term , which means when applied to a single argument (presumed to be of type Var ), as in your rename(n) (which can be more concisely written as rename n ), you get a value of type Var -> Term -> Term , not one of type Term as you clearly want. rename类型为Var -> Var -> Term -> Term ,这意味着当应用于单个参数(假定为Var类型)时,如在您的rename(n) (可以更简洁地写为rename n ),你得到一个Var -> Term -> Term类型的值,而不是你明确想要的Term类型。 To get that, you have to apply rename to 3 arguments (of the appropriate types), not just 1.为此,您必须将rename应用于 3 个(适当类型的)参数,而不仅仅是 1 个。

The following will fix the mentioned errors - although I haven't tested it to see if there are any more errors, nor am I totally sure I've understood the intended behaviour of your function (although I am somewhat confident on that).以下将修复提到的错误 - 尽管我没有测试它以查看是否还有更多错误,我也不完全确定我已经理解您的函数的预期行为(尽管我对此有些信心)。

I have also removed some unnecessary parentheses, and redefined newZ1 and newZ2 to be what I believed you intended, rather than being defined in terms of themselves.我还删除了一些不必要的括号,并将newZ1newZ2重新定义为我认为你想要的,而不是根据它们本身来定义。

rename :: Var -> Var -> Term -> Term
rename x y (Variable z)     
    | z == x    = Variable y
    | otherwise = Variable z

rename x y (Lambda z n)
    | z == x    = Lambda z n
    | otherwise = Lambda z newN
                  where newN = rename x y n

rename x y (Apply  n m) = Apply newZ1 newZ2
    where newZ1 = rename x y n
          newZ2 = rename x y m

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM