カスタムモナドトランスを作成するために(>> =)関数を実装しようとするときにエラーを入力します

StackOverflow https://stackoverflow.com/questions/2661895

質問

将来のプロジェクトのためにMonad Transformerを作成しようとしていますが、残念ながら、Monad Typeclasse(>> =)関数の実装は機能しません。

まず第一に、根底にあるモナドの実装は次のとおりです。

newtype Runtime a = R { 
  unR :: State EInfo a
} deriving (Monad)

ここで、Monad Typeclasseの実装はGHCによって自動的に行われます( GeneralizedNewtypeDeriving 言語プラグマ)。モナドトランスはそうであると定義されています:

newtype RuntimeT m a = RuntimeT {
  runRuntimeT :: m (Runtime a)
} 

問題は、私がMonad Typeclasseの(>> =)関数を導入する方法から生じます。

instance (Monad m) => Monad (RuntimeT m) where
    return a = RuntimeT $ (return . return) a
    x >>= f =  runRuntimeT x >>= id >>= f

私がそれを見る方法、最初 >>= 基礎となる走り m モナド。したがって、 runRuntimeT x >>= タイプの値を返します Runtime a (右 ?)。次に、次のコード、 id >>=, 、タイプの値を返す必要があります a. 。この値は、タイプの関数fに渡されます f :: (Monad m) => a -> RuntimeT m b.

そして、ここにタイプの問題があります: f 関数のタイプは、(>> =)関数で必要なタイプと一致しません。 JOWこのコヒーレントを作ることはできますか?なぜこれがうまくいかないのかわかりますが、それを機能ナルに変えることはできません。

編集:エラーメッセージ:

Core.hs:34:4:
    Occurs check: cannot construct the infinite type: m = RuntimeT m
    When generalising the type(s) for `>>='
    In the instance declaration for `Monad (RuntimeT m)'
Failed, modules loaded: none.

助けてくれてありがとう、そして私のメッセージの欠陥を修正することをheしないでください、
チャーリーP.

役に立ちましたか?

解決

リード・バートンが言ったことから続く StateT - これがあなたが定義する方法です RuntimeT 使用 StateT. 。 Runtime その後、モナドは、IDモナドを使用して些細なことに定義できます。

newtype RuntimeT m a = R { 
  unR :: StateT EInfo m a
}

type Runtime = RuntimeT Identity

instance Monad m => Monad (RuntimeT m) where
    return = R . return

    (R m) >>= f = R (m >>= unR . f)

他のヒント

いつもの StateT s m モナドは送信します as -> m (a, s) しかし、あなたは一緒に働いています m (s -> (a, s)) 代わりは。後者が将軍のためのモナドを形成するとは思わない s. 。あなたはただ使いたくないのですか? StateT?


これが私が考えない理由です am (s -> (a, s)) モナドです:書くこと >>= タイプの引数を取る関数が必要です

m (s -> (a, s))
a -> m (s -> (b, s))

タイプの値を返します

m (s -> (b, s))

「エフェクト」(すなわち fmap (const ()))結果は最初の議論のものでなければなりません。 a 2番目の引数に渡す。以来 m 結果タイプの外側にのみ表示され、2番目の引数をまったく使用することはできません。 m 紹介します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top