【问题标题】:Haskell Church Numerals with custom types具有自定义类型的 Haskell Church 数字
【发布时间】:2021-07-02 19:37:14
【问题描述】:

我正在尝试解决 Church 数字解析器我有一个自定义类型,可以区分变量、lambda 和应用程序

type Var = String

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

我有一个函数叫church 我可以为不同的教堂手动定义一个案例。所以让我们说:

  • church 0Lambda "f" (Lambda "x" (Variable "x"))
  • church 1 应该输出Lambda "f" (Lambda "x" (Apply (Variable "f") (Variable "x")))
  • church 2 应该输出Lambda "f" (Lambda "x" (Apply (Variable "f") (Apply (Variable "f") (Variable "x"))))

等等。

我已经尝试按照以下方式递归调用教堂函数:

church :: Int -> Term
church 0 = Lambda "f" (Lambda "x" (Variable  "x"))
church i = Apply (church(i -1)) (Apply (Variable "f") (Variable "x"))

但是,Lambda "f" (Lambda "x" 的部分也不断重复

我尝试过的另一种方法是

church :: Int -> Term
church 0 = Lambda "f" (Lambda "x" (Variable  "x"))
church i = Apply (church (i -1)) (Apply (Variable "f") (Variable "x"))

但是,这也会产生复制 lambda 的结果。我在这里错过了什么吗?怎么只能重复申请部分(Apply (Variable "f") (Variable "x"))

【问题讨论】:

  • 第一个代码片段的间距看起来不对,它呈现为church0churchi
  • 好地方。更新了旧约。

标签: haskell lambda-calculus


【解决方案1】:

所有教堂数字都以\f -> (\i -> …) 开头,这意味着我们的函数应该如下所示:

church :: Int -> Term
church n = Lambda f (Lambda x (go n))

我们仍然需要实现go :: Int -> Term。因此,这意味着对于go,我们必须找到一个看起来像这样的函数:

go 0 = Variable "x"
go 1 = Apply (Variable ("f")) (Variable "x")
go 2 = Apply (Variable "x") (Apply (Variable ("f")) (Variable "x"))

所以对于go <i>n</i>,我们必须返回一个Variable "x",并用Apply (Variable "x")

包裹在n 个项目中

因此,实现应该如下所示:

go :: Int -> Term
go 0 = Variable "x"
go n = … (go (n-1))

我将实施 作为练习。

【讨论】:

    猜你喜欢
    • 2011-12-20
    • 2012-03-12
    • 1970-01-01
    • 1970-01-01
    • 2019-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多