haskell - Transformation under Transformers -
i'm having bit of difficulty monad transformers @ moment. i'm defining few different non-deterministic relations make use of transformers. unfortunately, i'm having trouble understanding how translate cleanly 1 effectful model another.
suppose these relations "foo" , "bar". suppose "foo" relates , bs cs; suppose "bar" relates bs , cs ds. define "bar" in terms of "foo". make matters more interesting, computation of these relations fail in different ways. (since bar relation depends on foo relation, failure cases superset.) therefore give following type definitions:
data foofailure = foofailure string data barfailure = barspecificfailure | barfoofailure foofailure type foom = listt (eithert foofailure (reader context)) type barm = listt (eithert barfailure (reader context))
i expect able write relations following function signatures:
foo :: -> b -> foom c bar :: b -> c -> barm d
my problem that, when writing definition "bar", need able receive errors "foo" relation , represent them in "bar" space. i'd fine function of form
convert :: (e -> e') -> listt (eithert e (reader context) -> listt (eithert e' (reader context)
i can write little beast running listt, mapping on eithert, , reassembling listt (because happens m [a] can converted listt m a). seems... messy.
there's reason can't run transformer, stuff under it, , generically "put back"; transformer ran might have effects , can't magically undo them. there way in can lift function far enough transformer stack work me don't have write convert
function shown above?
i think convert answer, , using control.monad.morph
, control.monad.trans.either
it's (almost) simple write:
convert :: (monad m, functor m, mfunctor t) => (e -> e') -> t (eithert e m) b -> t (eithert e' m) b convert f = hoist (bimapeithert f id)
the slight problem listt
isn't instance of mfunctor
. think author boycotting listt
because doesn't follow monad transformer laws though because it's easy write type-checking instance
instance mfunctor listt hoist nat (listt mas) = listt (nat mas)
anyway, take @ control.monad.morph
dealing natural transformations on (parts of) transformer stacks. i'd fits definition of lifting function "just enough" stack.
Comments
Post a Comment