首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否可以使用迭代增量在类型化的教会数字上实现加法?

是否可以使用迭代增量在类型化的教会数字上实现加法?
EN

Stack Overflow用户
提问于 2014-05-16 23:26:06
回答 1查看 308关注 0票数 4

我无法找到一种将加法定义为重复增量的方法,尽管在一种非类型化的语言中可以这样做。这是我的代码:

代码语言:javascript
复制
{-# LANGUAGE RankNTypes #-}
type Church = forall a . (a -> a) -> (a -> a)

zero :: Church
zero = \f -> id

inc :: Church -> Church
inc n = \f -> f . n f

-- This version of addition works
add1 :: Church -> Church -> Church
add1 n m = \f -> n f . m f

-- This version gives me a compilation error
add2 :: Church -> Church -> Church
add2 n m = n inc m

我为add2获得的编译错误是

代码语言:javascript
复制
Couldn't match type `forall a1. (a1 -> a1) -> a1 -> a1'
                  with `(a -> a) -> a -> a'
    Expected type: ((a -> a) -> a -> a) -> (a -> a) -> a -> a
      Actual type: Church -> (a -> a) -> a -> a
    In the first argument of `n', namely `inc'
    In the expression: n inc m
    In an equation for `add2': add2 n m = n inc m

为什么这是个错误?Church不是((a->a) -> a -> a)的同义词吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-05-17 03:30:43

不管我添加了什么额外的类型注释,我都无法让您的代码键入,尽管我可能不够聪明。(我还尝试添加ImpredicativeTypes。)我认为这里的问题是在定义中

代码语言:javascript
复制
type Church = forall a. (a -> a) -> (a -> a)

a只能用秩-0类型实例化(即没有foralls在内部),而Church本身并不是,所以不能将这样定义的教会数字应用到inc中。

然而,有一个相对简单的解决方法,它稍微冗长,但使所有事情都很好地工作,否则:将Church变成一个新类型,而不是一个类型,这样就可以从外部把它看作是单形的。以下所有工作:

代码语言:javascript
复制
{-# LANGUAGE RankNTypes #-}
newtype Church = Church { runChurch :: forall a . (a -> a) -> (a -> a) }

zero :: Church
zero = Church (\f -> id)

inc :: Church -> Church
inc n = Church (\f -> f . runChurch n f)

add2 :: Church -> Church -> Church
add2 n = runChurch n inc
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23705936

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档