traversal with an arrow

Dear Café, Is there prior art to the following generalisation? A Hoogle search for the type signatures did not turn up anything. import Control.Arrow import Control.Monad (foldM) -- | Categories which every Traversable is a functor in. -- For Traversable t, the instance should satisfy -- -- @ -- foldMapArrow f = foldMapArrow id . traverseArrow f -- @ class Arrow a => ArrowTraverse a where traverseArrow :: Traversable t => a x y -> a (t x) (t y) foldArrow :: Foldable t => a (y,x) y -> a (y,t x) y instance ArrowTraverse (->) where traverseArrow = fmap foldArrow f = uncurry ((foldl.curry) f) instance Monad m => ArrowTraverse (Kleisli m) where traverseArrow (Kleisli k) = Kleisli (mapM k) foldArrow (Kleisli k) = (Kleisli . uncurry) (foldM (curry k)) -- | Generalizes foldMap. -- For Kleisli m, this function is also known as foldMapM. foldMapArrow :: (ArrowTraverse a, Foldable f, Monoid y) => a x y -> a (f x) y foldMapArrow f = (arr (const mempty) &&& id) >>> foldArrow ((id *** f) >>> arr (uncurry mappend)) The thing is that there are more instances for this class, for example by using Ross Paterson's arrow transformers [1]. I found myself implementing an arrow that is a Kleisli arrow with a reader context. Neither the standard arrow machinery nor the arrows package seem to grant me the power to write a traverseArrow for it. Either it can't be done, or my arrow-fu is not strong enough. Olaf [1] https://hackage.haskell.org/package/arrows

On Fri, 2022-06-17 at 16:19 +0100, Dan Dart wrote:
Is there prior art to the following generalisation?
Hello, that reminds me of a Profunctor - you could manipulate via Profunctor, since all arrows are Profunctors via a WrappedArrow newtype. Maybe Strong too? I forget which way round those go.
Cheers
Aha - profunctors weren't on my map, thanks for pointing me to it. So the desired arrows r -> a -> m b could be expressed as Cayley ((->) r) (Kleisli m) a b with module Data.Profunctor.Traversing defining the desired traversal. Further the implementation seems considerably simpler than the arrow implementation, as the latter uses currying, flipping etc. The only downside is that profunctors has heavier dependencies than arrows. Hooray Haskell Café! Olaf

On Fri, Jun 17, 2022 at 05:01:55PM +0200, Olaf Klinke wrote:
Is there prior art to the following generalisation?
traverseArrow :: Traversable t => a x y -> a (t x) (t y)
Perhaps you are looking for this: https://github.com/tomjaguarpaw/Arrows2/issues/3#issuecomment-561973678

There are some constructs like this in Dunai and Yampa (but not generalized). The first one indeed uses ArrowChoice: https://hackage.haskell.org/package/dunai-0.8.2/docs/src/Data.MonadicStreamF... The other two seem to be implementing some similar (ad hoc) choice, but it can be hard to tell sometimes: https://hackage.haskell.org/package/dunai-0.8.2/docs/src/Control.Monad.Trans... https://hackage.haskell.org/package/Yampa-0.13.5/docs/src/FRP.Yampa.Switches... Ivan On Fri, 17 Jun 2022 at 11:29, Tom Ellis < tom-lists-haskell-cafe-2017@jaguarpaw.co.uk> wrote:
On Fri, Jun 17, 2022 at 05:01:55PM +0200, Olaf Klinke wrote:
Is there prior art to the following generalisation?
traverseArrow :: Traversable t => a x y -> a (t x) (t y)
Perhaps you are looking for this:
https://github.com/tomjaguarpaw/Arrows2/issues/3#issuecomment-561973678 _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
participants (4)
-
Dan Dart
-
Ivan Perez
-
Olaf Klinke
-
Tom Ellis