2016-05-29 2 views
0

私はcontinuation passing style tutorialを見ていますが、次の機能の種類を理解できません。 chainCPSの変数のタイプは?

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を見ることができるのAtomエディタが提供する型情報を見る:

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 

上記は、以下の改造です。さらにzxx :: aです。

これについて私に混乱しているのは、zz :: a -> rであるということです。

つまり、s zは、〜sを適用した後に、rのタイプである必要があります。

もしそうなら、最終的なタイプはどのように(b -> r) -> rになるのですか?

編集:はk ...右です。つまり、zは実際にはa -> rのタイプです。しかし、それではなぜ型チェックに失敗するのでしょうか? s zszを適用した後に型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

いいえ。 z someArgはタイプrであり、someArgのタイプがaである場合はtrueですが、ではなくsが適用されます。ここで

代わりに、私たちはそうzsの引数の型と一致する

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

を持っています。したがって、結果のタイプは、の(a -> r) -> rの結果になります。

+0

私は自分の用語が混ざっていると思います。しかし、上記のように 'z :: a - > r 'と明示的に' z'の型を書き出すと、なぜ型エラーになるのですか? –

+0

@MarkoGrdinicその署名の間違ったデフォルトの解釈規則のため。簡単に言えば、Haskellは各署名が他の署名とは独立していると仮定しているので、 'z :: a - > r 'の' a'は 'chainCPS'の署名の' a'とは無関係です。 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

関連する問題