1

継続渡しスタイルのチュートリアルを見ていますが、次の関数の型がわかりません。

  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) -> rk :: b -> r. さらにzxタイプx :: aです。

これについて私が混乱しているのは、それzが type であることですz :: a -> r

つまり、 に適用した後s zの型である必要があります。rzs

もしそうなら、最終的な型はどのように出てき(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
4

1 に答える 1

2

つまり、 に適用した後s zの型である必要があります。rzs

いいえ。がタイプの場合、がz someArgタイプであることは事実ですが、ここではではなくを適用しています。rsomeArgasz

ここでは代わりに

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

sozの引数の型と一致しますs。したがって、結果の型は の結果であり(a -> r) -> r、これはrです。

于 2016-05-29T11:24:41.890 に答える