idioms ... for using Control.Applicative.WrapMonad or Control.Arrow.Kleisli?

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.

Nicolas Frisby wrote:
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
onKleisli :: (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.
Yep, I don't think you can avoid wrapping and unwrapping a newtype. While not directly related, I wonder whether Conor McBride's bag of tricks http://www.haskell.org/pipermail/libraries/2008-January/008917.html might be of help. Regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com
participants (2)
-
Heinrich Apfelmus
-
Nicolas Frisby