Я смотрю на 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
Глядя на информацию типа предоставленной редактором Atom я могу видеть, что s :: (a -> r) -> r
, f :: a -> (b -> r) -> r
, k :: b -> r
. Futhermore in z
x
имеет тип 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
Я предполагаю, что я перепутал терминологию. Хотя, почему приведенное выше дает ошибку типа, когда я выписываю тип 'z' явно как' z :: a -> r', как в приведенном выше? –
@MarkoGrdinic Из-за ошибочного правильного правила интерпретации этой подписи. Вкратце говоря, Haskell предполагает, что каждая подпись независима от других, поэтому ваш 'a' в' z :: a -> r' не связан с 'a' в сигнатуре' chainCPS'. Вы можете сказать Haskell, что они действительно то же самое, если вы пишете «chainCPS :: forall a b r». ... "и активировать расширение ScopedTypeVariables. https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#lexically-scoped-type-variables – chi