【问题标题】:Converting from Church Encoding to Numerals从教堂编码转换为数字
【发布时间】:2019-11-04 05:15:49
【问题描述】:

我正在尝试将 Church Encoding 转换为数字。我已经定义了自己的 Lambda 定义如下:

type Variable = String

data Lambda = Lam Variable Lambda
            | App Lambda Lambda
            | Var Variable
            deriving (Eq, Show)

我已经写了一个数字到教堂编码的转换,它可以按照我的预期工作,我是这样定义的:

toNumeral :: Integer -> Lambda
toNumeral n = Lam "s" (Lam "z" (wrapWithAppS n (Var "z")))
  where
    wrapWithAppS :: Integer -> Lambda -> Lambda
    wrapWithAppS i e
        | i == 0 = e
        | otherwise = wrapWithAppS (i-1) (App (Var "s") e)

我运行了自己的测试,这是测试 0、1 和 2 时终端的输出:

*Church> toNumeral 0
Lam "s" (Lam "z" (Var "z"))
*Church> toNumeral 1
Lam "s" (Lam "z" (App (Var "s") (Var "z")))
*Church> toNumeral 2
Lam "s" (Lam "z" (App (Var "s") (App (Var "s") (Var "z"))))

现在我正试图做相反的事情,我只是无法围绕需要传递的参数。这是我所拥有的:

fromNumeral :: Lambda -> Maybe Integer
fromNumeral  (Lam s (Lam z (App e (Var x))))
    | 0 == x = Just 0
    | ...

我尝试将(App e (Var x)) 替换为(Var x),但是当我尝试测试将教堂编码从0 转换为Just 0 的基本情况时,两者都出现此错误:

*** Exception: Church.hs:(166,1)-(167,23): Non-exhaustive patterns in function fromNumeral

我理解 3 个数字的 lambda 编码的方式是这样的:

0:\s。 \z。 z

1:\s。 \z。 sz

2:\s。 \z。 s (s z)

所以我假设我的逻辑是正确的,但我很难弄清楚反向转换是如何进行的。我对 Haskell 还很陌生,因此非常感谢任何帮助解释我可能做错的事情。

【问题讨论】:

    标签: haskell lambda-calculus church-encoding


    【解决方案1】:

    你应该匹配外部的(Lam "s" (Lam "z" )),但是内部的Apps 链应该被递归解析,镜像它的构造方式:

    fromNumeral (Lam s (Lam z apps)) = go apps
        where
            go (Var x) | x == z = Just 0
            go (App (Var f) e) | f == s = (+ 1) <$> go e
            go _ = Nothing
    
    fromNumeral _ = Nothing
    

    【讨论】:

    • 谢谢,有道理!我只需将 s 切换为 (Var s) 即可工作,因为我将变量定义为字符串,因此如果没有此更改,则相等性不起作用。如果我可能会问,第二行表示什么,我知道您在基本情况下加 1,但使用 的语法让我失望。
    • 2.抱歉,我错过了嵌套的Var。我已经更新了答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-05
    • 1970-01-01
    • 1970-01-01
    • 2016-03-28
    • 2014-12-01
    • 1970-01-01
    • 2011-09-29
    相关资源
    最近更新 更多