Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combining proxies with different EitherT in base monad

For example, having...

consumer :: Proxy p => () -> Consumer p a (EitherT String IO) ()
producer :: Proxy p => () -> Producer p a (EitherT ByteString IO) r

... how do I make this work?

session :: EitherT ByteString (EitherT String IO) ()
session = runProxy $ producer >-> consumer

Note: I've read Mixing Base Monads in Control.Proxy.Tutorial. I get the first example but can't understand the contrived example. More examples, not so obvious but not so contrived, might clarify how to use hoist and lift to match any combination of base monads.

like image 734
Danny Navarro Avatar asked Dec 02 '22 20:12

Danny Navarro


1 Answers

Suppose you have a monad transformer stack like MT1 MT2 MT3 M a where M is the base monad.

Using lift, you can add a new monad transformer to the left. It can be any transformer, so let's symbolize it by ?.

lift :: MT1 MT2 MT3 M a -> ? MT1 MT2 MT3 M a

Using hoist, you can manipulate the monad stack to the right of the leftmost element. Manipulate it how? For example by supplying a lift:

hoist lift :: MT1 MT2 MT3 M a -> MT1 ? MT2 MT3 M a

Using combinations of hoist and lift, you can insert these "wildcards" at any point in the monad transformer stack.

hoist (hoist lift) :: MT1 MT2 MT3 M a -> MT1 MT2 ? MT3 M a

hoist (hoist (hoist lift)) :: MT1 MT2 MT3 M a -> MT1 MT2 MT3 ? M a

This technique can be used to equalize the two monad stacks from your example.

like image 92
danidiaz Avatar answered Dec 04 '22 11:12

danidiaz