StateT g (Either E) T
をExceptT E (StateT g Identity) T
に変換するには?内外のモナドを交換する
恐らく、traverse
とhoist
のいくつかの組み合わせが役に立つでしょう。
StateT g (Either E) T
をExceptT E (StateT g Identity) T
に変換するには?内外のモナドを交換する
恐らく、traverse
とhoist
のいくつかの組み合わせが役に立つでしょう。
You can't exchange an arbitrary pair of monads。しかし、これらの2つの特定のモナドを交換することができます。それらのモナド変圧器の定義にnewtype
を展開するのが最も簡単です。あなたの最初の型の式でnewtype
Sを拡大
考える
newtype StateT s m a = StateT { runStateT :: s -> m (s, a) }
と
newtype ExceptT e m a = ExceptT { runExceptT :: m (Either e a) }
は、第二のために我々が得るのに対し、私たちに同型
StateT s (Either e) a <-> s -> Either e (s, a)
を与える
ExceptT e (StateT s Identity) a <-> s -> (s, Either e a)
Either e (s, a)
にはs
が含まれていても含まれていなくてもかまいませんが、(s, Either e a)
は常に存在します。さて、関数内でタプルを入れるだけで後者から前者に行くことができますが、逆にいくらかのドメイン固有の推論が必要です:計算がエラーを投げた場合、状態をそのままキャッチャーに渡す必要がありますエラーのこれは正しいことですか?それはむしろ議論の余地があります。
stateTEitherToExceptTState :: (s -> Either e (s, a)) -> (s -> (s, Either e a))
stateTEitherToExceptTState f s =
case f s of
Left e -> (s, Left e)
Right sa -> fmap Right sa
私は 'stateTEitherToExceptTState'が有効なモナドモーフィズムではないと思います。 'm 'が失敗しないアクションであり、' f'が常に失敗する 'fle'がある場合、' morph(m >> = f) 'は' morph m> = morphに等しくありません。 f 'である。 – danidiaz
'StateT g(Either e)t'が失敗すると、状態を提供しません。対応する「ExceptT e(StateT g Identity)tは何をすべきですか? – danidiaz
正確な定義を思い出すことはできませんが、状態によっては最初のモナドが失敗することはありません(たとえば、状態が偶数の場合)。 – chi