我正在查看continuation passing style tutorial,无法理解以下函数中的类型。
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
的{{1}}类型为x :: a
。
令我感到困惑的是,z
的类型为z :: a -> r
。
这意味着在将s z
应用于r
之后,z
应为s
类型。
如果是这样,最终类型如何出现在(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
答案 0 :(得分:1)
这意味着在将
s z
应用于r
之后,z
应为s
类型。
不。确实z someArg
属于r
类型,而someArg
属于a
类型,但此处我们正在应用s
,而不是z
这里我们有
s :: (a -> r) -> r
z :: (a -> r)
所以z
匹配s
参数的类型。因此,结果类型是(a -> r) -> r
的结果,r
。