Discussion: fold the Alts

We've had First and Last in Data.Monoid for some time, and we now have Alt as well. Unfortunately, we don't have nice convenient functions for using them, the way we have sum and product to use Sum and Product. So we're stuck with funny-looking constructions like listToMaybe . mapMaybe f for lists, and nothing good for other containers. My thought (the names firstAlt and lastAlt would absolutely have to be changed to accommodate non-catch Alternatives, but I'm not inspired at present): firstAlt, lastAlt :: (Foldable f, Alternative m) => (a -> m b) -> f a -> m b firstAlt f = getAlt #. foldMap (Alt #. f) lastAlt f = getAlt #. getDual #. foldMap (Dual #. Alt #. f) where (#.) :: Coercible b c => (b -> c) -> (a -> b) -> (a -> c) f #. g = coerce g This specializes to Maybe very nicely: firstMaybe :: Foldable f => (a -> Maybe b) -> f a -> Maybe b firstMaybe = firstAlt lastMaybe :: Foldable f => (a -> Maybe b) -> f a -> Maybe b lastMaybe = lastAlt

Um, msum / asum?
On Sat, Nov 8, 2014 at 2:06 PM, David Feuer
We've had First and Last in Data.Monoid for some time, and we now have Alt as well. Unfortunately, we don't have nice convenient functions for using them, the way we have sum and product to use Sum and Product. So we're stuck with funny-looking constructions like listToMaybe . mapMaybe f for lists, and nothing good for other containers.
My thought (the names firstAlt and lastAlt would absolutely have to be changed to accommodate non-catch Alternatives, but I'm not inspired at present):
firstAlt, lastAlt :: (Foldable f, Alternative m) => (a -> m b) -> f a -> m b
firstAlt f = getAlt #. foldMap (Alt #. f)
lastAlt f = getAlt #. getDual #. foldMap (Dual #. Alt #. f)
where (#.) :: Coercible b c => (b -> c) -> (a -> b) -> (a -> c) f #. g = coerce g
This specializes to Maybe very nicely:
firstMaybe :: Foldable f => (a -> Maybe b) -> f a -> Maybe b firstMaybe = firstAlt
lastMaybe :: Foldable f => (a -> Maybe b) -> f a -> Maybe b lastMaybe = lastAlt
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

Ah, yes, it's lovely how I can look at a function one day and then forget
it exists the very next. Carry on!
On Sat, Nov 8, 2014 at 2:22 PM, Edward Kmett
Um, msum / asum?
On Sat, Nov 8, 2014 at 2:06 PM, David Feuer
wrote: We've had First and Last in Data.Monoid for some time, and we now have Alt as well. Unfortunately, we don't have nice convenient functions for using them, the way we have sum and product to use Sum and Product. So we're stuck with funny-looking constructions like listToMaybe . mapMaybe f for lists, and nothing good for other containers.
My thought (the names firstAlt and lastAlt would absolutely have to be changed to accommodate non-catch Alternatives, but I'm not inspired at present):
firstAlt, lastAlt :: (Foldable f, Alternative m) => (a -> m b) -> f a -> m b
firstAlt f = getAlt #. foldMap (Alt #. f)
lastAlt f = getAlt #. getDual #. foldMap (Dual #. Alt #. f)
where (#.) :: Coercible b c => (b -> c) -> (a -> b) -> (a -> c) f #. g = coerce g
This specializes to Maybe very nicely:
firstMaybe :: Foldable f => (a -> Maybe b) -> f a -> Maybe b firstMaybe = firstAlt
lastMaybe :: Foldable f => (a -> Maybe b) -> f a -> Maybe b lastMaybe = lastAlt
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

Er, actually, no. This is not quite right.
asum :: (Foldable t, Alternative f) => t (f a) -> f a
firstAlt :: (Foldable t, Alternative f) => (a -> f b) -> t a -> f b
If the container is a Functor, asum is good enough. In other cases, it
doesn't help any.
On Sat, Nov 8, 2014 at 2:27 PM, David Feuer
Ah, yes, it's lovely how I can look at a function one day and then forget it exists the very next. Carry on!
On Sat, Nov 8, 2014 at 2:22 PM, Edward Kmett
wrote: Um, msum / asum?
On Sat, Nov 8, 2014 at 2:06 PM, David Feuer
wrote: We've had First and Last in Data.Monoid for some time, and we now have Alt as well. Unfortunately, we don't have nice convenient functions for using them, the way we have sum and product to use Sum and Product. So we're stuck with funny-looking constructions like listToMaybe . mapMaybe f for lists, and nothing good for other containers.
My thought (the names firstAlt and lastAlt would absolutely have to be changed to accommodate non-catch Alternatives, but I'm not inspired at present):
firstAlt, lastAlt :: (Foldable f, Alternative m) => (a -> m b) -> f a -> m b
firstAlt f = getAlt #. foldMap (Alt #. f)
lastAlt f = getAlt #. getDual #. foldMap (Dual #. Alt #. f)
where (#.) :: Coercible b c => (b -> c) -> (a -> b) -> (a -> c) f #. g = coerce g
This specializes to Maybe very nicely:
firstMaybe :: Foldable f => (a -> Maybe b) -> f a -> Maybe b firstMaybe = firstAlt
lastMaybe :: Foldable f => (a -> Maybe b) -> f a -> Maybe b lastMaybe = lastAlt
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

We don't try to provide every single function that could map to any monoid
in Data.Monoid in Data.Foldable.
*e.g.* by the same token we also don't have versions that take a function
and then compute a sum or product.
Global namespace in a library like base is a fairly precious resource,
because any name you take is taken from all users who use unqualified
imports.
The assumption is rather implicit that if you need something more exotic
you can roll it yourself from the parts available to you.
-Edward
On Sat, Nov 8, 2014 at 2:35 PM, David Feuer
Er, actually, no. This is not quite right.
asum :: (Foldable t, Alternative f) => t (f a) -> f a firstAlt :: (Foldable t, Alternative f) => (a -> f b) -> t a -> f b
If the container is a Functor, asum is good enough. In other cases, it doesn't help any.
On Sat, Nov 8, 2014 at 2:27 PM, David Feuer
wrote: Ah, yes, it's lovely how I can look at a function one day and then forget it exists the very next. Carry on!
On Sat, Nov 8, 2014 at 2:22 PM, Edward Kmett
wrote: Um, msum / asum?
On Sat, Nov 8, 2014 at 2:06 PM, David Feuer
wrote: We've had First and Last in Data.Monoid for some time, and we now have Alt as well. Unfortunately, we don't have nice convenient functions for using them, the way we have sum and product to use Sum and Product. So we're stuck with funny-looking constructions like listToMaybe . mapMaybe f for lists, and nothing good for other containers.
My thought (the names firstAlt and lastAlt would absolutely have to be changed to accommodate non-catch Alternatives, but I'm not inspired at present):
firstAlt, lastAlt :: (Foldable f, Alternative m) => (a -> m b) -> f a -> m b
firstAlt f = getAlt #. foldMap (Alt #. f)
lastAlt f = getAlt #. getDual #. foldMap (Dual #. Alt #. f)
where (#.) :: Coercible b c => (b -> c) -> (a -> b) -> (a -> c) f #. g = coerce g
This specializes to Maybe very nicely:
firstMaybe :: Foldable f => (a -> Maybe b) -> f a -> Maybe b firstMaybe = firstAlt
lastMaybe :: Foldable f => (a -> Maybe b) -> f a -> Maybe b lastMaybe = lastAlt
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

You make a good point, yes.
On Sat, Nov 8, 2014 at 2:46 PM, Edward Kmett
We don't try to provide every single function that could map to any monoid in Data.Monoid in Data.Foldable.
*e.g.* by the same token we also don't have versions that take a function and then compute a sum or product.
Global namespace in a library like base is a fairly precious resource, because any name you take is taken from all users who use unqualified imports.
The assumption is rather implicit that if you need something more exotic you can roll it yourself from the parts available to you.
-Edward
On Sat, Nov 8, 2014 at 2:35 PM, David Feuer
wrote: Er, actually, no. This is not quite right.
asum :: (Foldable t, Alternative f) => t (f a) -> f a firstAlt :: (Foldable t, Alternative f) => (a -> f b) -> t a -> f b
If the container is a Functor, asum is good enough. In other cases, it doesn't help any.
On Sat, Nov 8, 2014 at 2:27 PM, David Feuer
wrote: Ah, yes, it's lovely how I can look at a function one day and then forget it exists the very next. Carry on!
On Sat, Nov 8, 2014 at 2:22 PM, Edward Kmett
wrote: Um, msum / asum?
On Sat, Nov 8, 2014 at 2:06 PM, David Feuer
wrote: We've had First and Last in Data.Monoid for some time, and we now have Alt as well. Unfortunately, we don't have nice convenient functions for using them, the way we have sum and product to use Sum and Product. So we're stuck with funny-looking constructions like listToMaybe . mapMaybe f for lists, and nothing good for other containers.
My thought (the names firstAlt and lastAlt would absolutely have to be changed to accommodate non-catch Alternatives, but I'm not inspired at present):
firstAlt, lastAlt :: (Foldable f, Alternative m) => (a -> m b) -> f a -> m b
firstAlt f = getAlt #. foldMap (Alt #. f)
lastAlt f = getAlt #. getDual #. foldMap (Dual #. Alt #. f)
where (#.) :: Coercible b c => (b -> c) -> (a -> b) -> (a -> c) f #. g = coerce g
This specializes to Maybe very nicely:
firstMaybe :: Foldable f => (a -> Maybe b) -> f a -> Maybe b firstMaybe = firstAlt
lastMaybe :: Foldable f => (a -> Maybe b) -> f a -> Maybe b lastMaybe = lastAlt
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
participants (2)
-
David Feuer
-
Edward Kmett