Haskell chainCPS中变量的类型是什么?

Haskell chainCPS中变量的类型是什么?,haskell,types,continuation-passing,Haskell,Types,Continuation Passing,我正在查看,无法理解以下函数中的类型 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 以上是对以下内容的改造:

我正在查看,无法理解以下函数中的类型

  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
以上是对以下内容的改造:

  chainCPS :: ((a -> r) -> r) -> (a -> ((b -> r) -> r)) -> ((b -> r) -> r)
  chainCPS s f = \k -> s $ \x -> f x $ k
查看Atom编辑器提供的类型信息,我可以看到
s::(a->r)->r
f::a->(b->r)->r
k::b->r
。此外,在
z
中,
x
的类型为
x::a

让我困惑的是,
z
的类型是
z::a->r

这意味着在将
z
应用于
s
之后,
sz
应为
r
类型

如果是这样的话,最后的类型是如何变成
(b->r)->r

编辑:
b->r
来自
k
…右侧。正如编辑所说,这意味着
z
实际上是
a->r
类型。但是为什么下面的类型检查失败呢

  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
这意味着在将
z
应用于
s
之后,
sz
应为
r
类型

没有。当
someArg
属于
a
类型时,
zsomearg
属于
r
类型,这是事实,但这里我们应用的是
s
,而不是
z

我们有

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

因此
z
s
的参数类型匹配。因此,结果类型是
(a->r)->r
的结果,这就是
r

我想我把术语弄错了。尽管如此,当我将
z
的类型显式写为
z::a->r
时,为什么上面给出了一个类型错误?因为该签名的默认解释规则可能是错误的。简而言之,Haskell假设每个签名都独立于其他签名,因此
z::a->r
中的
a
chainCPS
签名中的
a
无关。如果您编写
chainCPS::forall a b r….,您可以告诉Haskell它们确实是相同的东西
并启用
ScopedTypeVariables
扩展。