Exchange of internal and external monads

How to convert StateT g (Either E) T to ExceptT E (StateT g Identity) T ?

Perhaps some combination of traverse and hoist may be useful hoist .

+5
source share
1 answer

You cannot exchange an arbitrary pair of monads . But you can exchange these two separate monads. The easiest way to understand is whether you extend the newtype in the definitions of these monad transformers.

Considering

 newtype StateT sma = StateT { runStateT :: s -> m (s, a) } 

and

 newtype ExceptT ema = ExceptT { runExceptT :: m (Either ea) } 

the newtype extension in your first type expression gives us an isomorphism

 StateT s (Either e) a <-> s -> Either e (s, a) 

whereas for the second we get

 ExceptT e (StateT s Identity) a <-> s -> (s, Either ea) 

Note that Either e (s, a) may or may not contain s , while (s, Either ea) always. Now you can go from the last to the first, just traverse with a tuple inside the function, but to switch to another path some domain-specific arguments are required: if the calculation causes an error, then we must discard the state without changes until the error catches. (Is it right to do this? I find this rather controversial.)

 stateTEitherToExceptTState :: (s -> Either e (s, a)) -> (s -> (s, Either ea)) stateTEitherToExceptTState fs = case fs of Left e -> (s, Left e) Right sa -> fmap Right sa 
+9
source

Source: https://habr.com/ru/post/1263177/


All Articles