私はExceptT a (StateT A M)
、いくつかの具象型A
とモナドのために、例えば、を取りM
、それらを新しいカスタムモナドにラップしようとしています。
最初にStateT A M
、 が他のコンテキストで頻繁に現れることを特定したので、それだけをモナドでラップしてから でラップするのが最善であると判断しM1
ましExceptT a M1
たM2
。
必要なプロパティは、のインスタンスとのクラスを作成M1
するM2
ことMonadState
ですM
(それが呼び出されたと仮定しましょうMyMonadClass
)。のインスタンスでもM2
ある必要がありますMonadError
。
まず、単純な型のシノニムから始めました。
type MyState = StateT A M
type MyBranch a = ExceptT a MyState
次に、最初にインスタンス宣言を(インスタンスを実装せずに)スケッチすると思いましたが、そこで最初に行き詰まりました。instance MonadState A (MyState)
正しい構文ではないようです。newtype MyState' a = StateT a M
作成してから作成する必要があると思いましたtype MyState = MyState A
(必要のない言語拡張機能は使用しないでください)。
しかし、シノニムを宣言に変換し始めると、 and型newtype
への接続が失われ始めました。StateT A M
ExceptT ...
newtype MyState' s a = MyState' { runMyState :: s -> (s, a) }
type MyState = MyState' A
newtype MyBranch e a = MyBranch { runMyBranch :: MyState (Either e a) }
すでに実装されているトランスフォーマーは姿を消し、あまり意味のないことをしようとしていると思います。だから私の質問は次のとおりです: この種の動作を新しい複合モナドに正しくラップして、下にあるレイヤーにアクセスできるようにすることで、不必要な持ち上げを回避し、物事を明確に整理することができます。