Church style lists: infinite type error when compiling but not interactively
I'm just starting to learn haskell and I'm trying to implement lists in a pure lambda calculus way (such as described in the wikipedia page for Church encoding).
The following function produces a "cannot construct the infinite type" at compile time. However, when I execute the code of the function interactively, it works. This is the code of the function:
showl l = isempty' l 0 (head' l)
And here is how I run it interactively (it works):
let l = (cons' 7 empty') in isempty' l 0 (head' l)
With the function showl
, I want to get the first element of a list (not a haskell list, but a list as defined in Church encoding) if it is not empty, and 0 otherwise. In details, isempty' l
returns a Church boolean, namely the function \ a b -> a
if the list l
is empty (True), and \ a b -> b
otherwise (False). This way, if True, showl
returns 0, and `(head' l)' otherwise (the first element of the list).开发者_运维问答
I suppose it's a problem with type inference, as suggested by the other questions about infinit type errors. But I don't see it, and since it works interactively, it must be fine... I'm confused.
Thanks
(the exact compiler output:
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.
and the functions I wrote to define Church style lists:
-- 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'))
)
It seems the compiler is getting confused here. Given an explicit type signature for your function (using Rank2Types
), it compiles nicely and works just fine.
{-# 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)
When running it interactively it works because the concrete types are available.
精彩评论