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.