I am looking at the continuation passing style tutorial and cannot understand the types in the following function.
chainCPS :: ((a -> r) -> r) -> (a -> ((b -> r) -> r)) -> ((b -> r) -> r)
chainCPS s f k = s z where
-- z :: (a -> r) -> a -> ((b -> r) -> r) -- Fails
z x = f x k
The above is the remodel of the following:
chainCPS :: ((a -> r) -> r) -> (a -> ((b -> r) -> r)) -> ((b -> r) -> r)
chainCPS s f = \k -> s $ \x -> f x $ k
Looking at the type info provided by the Atom editor I can see that s :: (a -> r) -> r
, f :: a -> (b -> r) -> r
, k :: b -> r
. Futhermore in z
the x
is of type x :: a
.
What is confusing to me about this is that z
is of type z :: a -> r
.
That means that s z
should be of type r
after applying z
to s
.
If so, how does the final type come out to (b -> r) -> r
?
Edit: The b -> r
comes from k
...right. That means z
really is of type a -> r
, as the editor says. But then why does the following fail typechecking?
chainCPS :: ((a -> r) -> r) -> (a -> ((b -> r) -> r)) -> (b -> r) -> r
chainCPS s f k = s z where
z :: a -> r
z x = f x k