3

2 つのモナドを構成する関数があります。

comp :: Monad m => m a -> m b -> m b

そして、 on が an の「内側」にあるようなモナドの 2 つのインスタンスMfunctor

ms :: Monad m => m String
ms = undefined

tma :: (Monad m, MFunctor t) => t m a
tma = undefined

今、私が作曲しようとするmstma

tmas = hoist (\ma -> comp ma ms) tma

このエラーが発生しています:

 Could not deduce (a ~ [Char])
    from the context (Monad m, MFunctor t)
      bound by the inferred type of
               comp :: (Monad m, MFunctor t) => t m b
      at Coroutine.hs:607:1-40
      `a' is a rigid type variable bound by
          a type expected by the context: m a -> m a at Coroutine.hs:607:8
    Expected type: m a
      Actual type: m String

これは、ainmsが任意の型でなければならないことを示しています: ms :: Monad m => m a.

これはなぜですかtma、特定のパラメータのモナドで構成する方法はありますか。

ホイストのシグネチャは次のとおりです。

hoist :: (Monad m, MFunctor t) => (forall a. m a -> n a) -> t m b -> t n b

しかし、それがforall私がやろうとしていることにどのように影響を与えているかを想像することはできません。

4

2 に答える 2

4

引数の順序を次のcompように切り替えます。

tmas = hoist (\ma -> comp ms ma) tma

-- or more simply:
tmas = hoist (comp ms) tma

その理由は、 のタイプcompが次のとおりであるためです。

comp :: (Monad m) => m a -> m b -> m b

ms2 番目の引数として、b型チェックを a として設定すると、次のようにStringなります。

(`comp` ms) :: (Monad m) => m a -> m String

...しかしms、最初の引数として設定すると、次のようにa型チェックされStringます。

(ms `comp`) :: (Monad m) => m b -> m b

hoist後者のタイプは、bが普遍的に量化される (つまり、「forall」される)ため、正しいタイプです。

正しさについてのあなたの質問に答えるために、その答えは、全称量化は、 への引数がhoistモナドの戻り値ではなく、モナド層のみを変更することを保証するということです。ただし、戻り値を変更することも意図している場合は、それhoistは望ましくありません。

于 2013-08-28T14:28:02.307 に答える
2

の型は、関数、つまり「コンテナ」型を変更するが型パラメータを同じに保つ関数をhoist期待していることを示しています。(forall a. m a -> n a)here は、forall提供する関数を特定のものに特化することはできませんがa、任意の型パラメーターに対して機能する必要があることを意味します。

使用しようとしている関数 ( \ma -> comp ma ms) には型があるため、コンテナー ( ) は同じままですが、型パラメーターが ( から ) に変更されるため、予想m a -> m Stringとはほとんど逆になります。hoistmaString

この場合の代わりに実際に探しているのhoistは、モナド関数を持ち上げて変換されたモナドで動作する関数だと思うので、代わりに次のMFunctorようなものが必要になります。

import Control.Monad.Trans.Class

tmas :: (Monad m, Monad (t m), MonadTrans t) => t m String
tmas = transLift (\ma -> comp ma ms) tma

transLift :: (Monad m, Monad (t m), MonadTrans t) => (m a -> m b) -> t m a -> t m b
transLift f tma = tma >>= lift . f . return
于 2013-08-28T12:37:57.957 に答える