Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Looking for a dual of ReaderT, which abstracts over the environment instead of monadic result

Tags:

haskell

Is the following abstraction with instances of Contravariant, Divisible and etc. already implemented in some package? I imply something in the spirit of the following compilable code:

newtype ReaderDual a m b =
  ReaderDual (b -> m a)

instance Contravariant (ReaderDual a m) where
  contramap ba (ReaderDual a') =
    ReaderDual $ a' . ba

instance (Applicative m, Monoid a) => Divisible (ReaderDual a m) where
  divide aToBC (ReaderDual b') (ReaderDual c') =
    ReaderDual $ \a -> aToBC a & \(b, c) -> (<>) <$> b' b <*> c' c
  conquer =
    ReaderDual $ \_ -> pure mempty

run :: ReaderDual a m b -> b -> m a
run (ReaderDual a') b =
  a' b
like image 956
Nikita Volkov Avatar asked Aug 09 '15 13:08

Nikita Volkov


1 Answers

You can build this type as a composition of Op from contravariant and Ap from reducers. Op a b is just b -> a, and has a Divisible instance for any Monoid a.

To get the behavior of your instance, we can use Ap m a, which provides a Monoid with mappend = liftA2 (<>) and mempty = pure mempty for any Applicative m and Monoid a.

type ReaderDual a m b = Op (Ap m a) b
like image 138
bennofs Avatar answered Oct 28 '22 15:10

bennofs