haskelldistributive

Is there any typeclass that defines the function from `a -> m b` to `m (a -> b)`?


The function from a -> m b to m (a -> b) rarely appears in programming, but can be made in the Reader monad. The following code is a tentative implementation. Does such a library exist?

class Monad m => MonadShift m where
  shift :: (a -> m b) -> m (a -> b)

instance MonadShift Identity where
  shift f = Identity (\x -> runIdentity (f x))

instance MonadShift m => MonadShift (ReaderT r m) where
  shift f = ReaderT (\r -> shift (\x -> runReaderT (f x) r))

Solution

  • It's a specialization of distribute :: Functor f => f (g a) -> g (f a) of the Distributive class where f is the Functor (->) b. Then you get the type signature:

    distribute :: (b -> g a) -> g (b -> a)
    

    Note that (1) this doesn't require g to be a Monad, but just a Functor, and (2) the Identity and ReaderT instances are basically the only instances that you can define:

    Categorically every Distributive functor is actually a right adjoint, and so it must be Representable endofunctor and preserve all limits. This is a fancy way of saying it is isomorphic to (->) x for some x.