开发者

Church style lists: infinite type error when compiling but not interactively

开发者 https://www.devze.com 2023-03-29 05:43 出处:网络
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).

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消