継続渡しスタイルのチュートリアルを見ていますが、次の関数の型がわかりません。
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
が type であることですz :: a -> r
。
つまり、 に適用した後s z
の型である必要があります。r
z
s
もしそうなら、最終的な型はどのように出てき(b -> r) -> r
ますか?
編集:b -> r
から来k
ます...右。編集者が言うように、それはz
本当に が typeであることを意味します。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