我刚开始学习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'))
)
答案 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)
以交互方式运行时,它可以使用,因为具体类型可用。