0
我正在查看continuation passing style tutorial,无法理解以下函数中的类型。chainCPS中的变量的类型是什么?
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
望着由凌编辑提供的类型信息,我可以看到s :: (a -> r) -> r
,f :: a -> (b -> r) -> r
,k :: b -> r
。还有更多z
x
是x :: a
。
什么令我困惑的是,z
是z :: a -> r
类型。
这意味着,应当s z
施加z
到s
后是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'明确地写为'z :: a - > r'时,上面给出了一个类型错误? –
@MarkoGrdinic由于该签名的默认解释规则可能是错误的。简而言之,Haskell假定每个签名都是独立于其他签名的,所以'z :: a - > r'中的'a'与'chainCPS'的签名中的'a'不相关。如果你编写'chainCPS :: forall a b r',你可以告诉Haskell他们确实是同一件事。 ...'并启用'ScopedTypeVariables'扩展。 https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#lexically-scoped-type-variables – chi