2016-05-29 78 views
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) -> rf :: a -> (b -> r) -> rk :: b -> r。还有更多zxx :: a

什么令我困惑的是,zz :: a -> r类型。

这意味着,应当s z施加zs后是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 

回答

1

这意味着,应当s z施加zs后是r类型。

没有。确实z someArgr类型,当someArga类型时,但这里我们应用s而不是z

在这里,而不是我们

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

所以zs参数的类型相匹配。因此,得到的类型是(a -> r) -> r的结果,即r

+0

我想我把我的术语弄混了。但是,为什么上面给出的类型'z'明确地写为'z :: a - > r'时,上面给出了一个类型错误? –

+0

@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

相关问题