教堂样式列表:编译时无限类型错误,但不是交互式

时间:2011-08-20 12:24:42

标签: haskell

我刚开始学习haskell,我正试图以纯lambda演算的方式实现列表(如the wikipedia page for Church encoding中所述)。

以下函数在编译时生成“无法构造无限类型”。但是,当我以交互方式执行函数代码时,它可以工作。这是函数的代码:

showl l = isempty' l 0 (head' l)

以下是我如何以交互方式运行它(它的工作原理):

let l = (cons' 7 empty') in isempty' l 0 (head' l)

使用函数showl,我想获取列表的第一个元素(不是haskell列表,而是教会编码中定义的列表),如果它不为空,则为0。详细地说,isempty' l返回一个Church布尔值,即如果列表\ a b -> a为空(True)则返回函数l,否则返回\ a b -> b(False)。这样,如果为True,showl将返回0,否则为(head'l)'(列表的第一个元素)。

我认为这是类型推断的问题,正如其他关于无限类型错误的问题所暗示的那样。但是我没有看到它,因为它以交互方式工作,它一定很好......我很困惑。

由于

(确切的编译器输出:

Occurs check: cannot construct the infinite type: t = t1 -> t -> t2
Probable cause: `isempty'' is applied to too many arguments
In the expression: isempty' l 0 (head' l)
In the definition of `showl': showl l = isempty' l 0 (head' l)
Failed, modules loaded: none.

以及我用来定义教堂风格列表的函数:

-- True and False
t a b = a
f a b = b

-- pairs
pair a b z = z a b
fst' p = p t
snd' p = p f

-- lists
empty' f x = x
isempty' l = l (\ a b -> f) t
cons' a l f x = f a (l f x)
head' l = l t 0
tail' l = fst' (l (\x p -> pair (snd' p) (cons' x (snd' p))) (pair empty' empty'))

1 个答案:

答案 0 :(得分:4)

似乎编译器在这里感到困惑。给定函数的显式类型签名(使用Rank2Types),它编译得很好并且工作正常。

{-# LANGUAGE Rank2Types #-}

type List a = forall b. (a -> b -> b) -> b -> b

showl :: Num a => List a -> a 
showl l = isempty' l 0 (head' l)

以交互方式运行时,它可以使用,因为具体类型可用。