[Haskell-cafe] idioms ... for using Control.Applicative.WrapMonad or Control.Arrow.Kleisli?

Nicolas Frisby nicolas.frisby at gmail.com
Mon Mar 1 13:31:04 EST 2010


Each time I find myself needing to use the wrapping functions
necessary for this embeddings, I grumble. Does anyone have a favorite
use-pattern for ameliorating these quickly ubiquitous conversions?

For runKleisli, I was considering something like

okKleisli ::
  (Control.Arrow.Kleisli m a b -> Control.Arrow.Kleisli m' a' b')
  -> (a -> m b) -> (a' -> m' b')
onKleisli f = Control.Arrow.runKleisli . f . Control.Arrow.Kleisli

but haven't really tested its usefulness. My most frequent use cases
usually include Arrow.first, Arrow.second, &&&, ***, or +++. E.g.

somefun :: (Monad m, Num a) => (a, d) -> m (a, d)
somefun = onKleisli Control.Arrow.first (\ a -> return (a + 1))

Perhaps a Control.Arrow.Kleisli, which would export (same-named)
Kleisli specializations of all the Control.Arrow methods? And an
analogous Control.Applicative.Monad? (Data.Traversable does this a
little bit to specialize its interface for monads, such as
Data.Traversable.sequence.)

While writing this, I realized that you can't leave the Arrow-ness of
Kleisli arrows implicit, since (->) a (m b) is two kinds of arrows
depending on context -- which is precisely what the Kleisli newtype
resolves. So I'm not seeing a reason to bring up the 'class
Applicative m => Monad m where' dispute.

Thanks for your time.


More information about the Haskell-Cafe mailing list