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))
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.