将来のプロジェクトのためにモナド変換子を作成しようとしていますが、残念ながら、モナド型クラスの (>>=) 関数の実装が機能しません。
まず、基礎となるモナドの実装は次のとおりです。
newtype Runtime a = R {
unR :: State EInfo a
} deriving (Monad)
ここで、Monad 型クラスの実装は GHC によって ( GeneralizedNewtypeDeriving
language プラグマを使用して) 自動的に行われます。モナド変換子は次のように定義されます。
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 >>=
は type の値を返す必要がありますa
。この値は、 type の関数 f に渡されf :: (Monad m) => a -> RuntimeT m b
ます。
ここで型の問題が発生します。f
関数の型が (>>=) 関数で必要な型と一致しません。これを首尾一貫させることができますか?これが機能しない理由はわかりますが、機能的なものに変えることはできません。
編集:エラーメッセージ:
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.
助けてくれてありがとう、
チャーリー P.