1

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
Marko Grdinić
  • 3,798
  • 3
  • 18
  • 21

1 Answers1

2

That means that s z should be of type r after applying z to s.

Nope. It is true that z someArg is of type r, when someArg is of type a, but here we are applying s, not z.

Here instead we have

s :: (a -> r) -> r
z :: (a -> r)

so z matches the type of the argument of s. Hence, the resulting type is the result of (a -> r) -> r, which is r.

chi
  • 111,837
  • 3
  • 133
  • 218
  • I guess I got my terminology mixed up. Though, why does the above give a type error when I write out the type of `z` explicitly as `z :: a -> r` as in the above? – Marko Grdinić May 29 '16 at 13:03
  • @MarkoGrdinic Because of an arguably wrong default interpretation rule of that signature. Briefly put, Haskell assumes each signature is independent from others, so your `a` in `z :: a -> r` is unrelated to the `a` in the signature of `chainCPS`. You can tell Haskell that they are indeed the same thing if you write `chainCPS :: forall a b r . ...` and enable the `ScopedTypeVariables` extension. https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#lexically-scoped-type-variables – chi May 29 '16 at 13:18