Argument order for Data.Map.adjustF

I managed to find an implementation of Control.Lens.At.at for Data.Map that's fast enough to be useful. The function will be named alterF to match the name of Data.Map.alter. The remaining question is what order the arguments should go in. I had thought to follow those of alter for consistency, giving alterF :: (Functor f, Ord k) => (Maybe a -> f (Maybe a)) -> k -> Map k a -> f (Map k a) Edward Kmett thinks the ergonomics of that order are terrible, and prefers to follow lens at, giving alterF :: (Functor f, Ord k) => k -> (Maybe a -> f (Maybe a)) -> Map k a -> f (Map k a) How do other people feel about this? David Feuer

On 8 May 2016 at 06:45, David Feuer
I managed to find an implementation of Control.Lens.At.at for Data.Map that's fast enough to be useful. The function will be named alterF to match the name of Data.Map.alter. The remaining question is what order the arguments should go in. I had thought to follow those of alter for consistency, giving
alterF :: (Functor f, Ord k) => (Maybe a -> f (Maybe a)) -> k -> Map k a -> f (Map k a)
Edward Kmett thinks the ergonomics of that order are terrible, and prefers to follow lens at, giving
alterF :: (Functor f, Ord k) => k -> (Maybe a -> f (Maybe a)) -> Map k a -> f (Map k a)
How do other people feel about this?
I have a slight preference for the first one as I'm more likely to be applying the same function over multiple keys than having the same key being altered with different functions.
David Feuer
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
-- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com http://IvanMiljenovic.wordpress.com

I do agree that it would be more consistent to use the alter ordering,
but I don't see many users who will reach for it as "generalized
alter".
Ultimately, I anticipate the major consumers of such a function would
be people using some lens package, either through us changing the
default definitions in lens to automatically use it on appropriate
versions of containers, or through using a more minimalist lens
package that doesn't provide lenses for containers -- most other
people will neither find the new operation nor care.
The former would require a flip for lens consumers to turn it back
into a lens, making it much harder to recognize as such.
-Edward
On Sat, May 7, 2016 at 4:45 PM, David Feuer
I managed to find an implementation of Control.Lens.At.at for Data.Map that's fast enough to be useful. The function will be named alterF to match the name of Data.Map.alter. The remaining question is what order the arguments should go in. I had thought to follow those of alter for consistency, giving
alterF :: (Functor f, Ord k) => (Maybe a -> f (Maybe a)) -> k -> Map k a -> f (Map k a)
Edward Kmett thinks the ergonomics of that order are terrible, and prefers to follow lens at, giving
alterF :: (Functor f, Ord k) => k -> (Maybe a -> f (Maybe a)) -> Map k a -> f (Map k a)
How do other people feel about this?
David Feuer

This might be a good case for having two names for the same function. Both
use cases seem reasonable, and I don't really want containers to be too
opinionated about the style of code using it.
On Sat, May 7, 2016, 7:59 PM Edward Kmett
I do agree that it would be more consistent to use the alter ordering, but I don't see many users who will reach for it as "generalized alter".
Ultimately, I anticipate the major consumers of such a function would be people using some lens package, either through us changing the default definitions in lens to automatically use it on appropriate versions of containers, or through using a more minimalist lens package that doesn't provide lenses for containers -- most other people will neither find the new operation nor care.
The former would require a flip for lens consumers to turn it back into a lens, making it much harder to recognize as such.
-Edward
I managed to find an implementation of Control.Lens.At.at for Data.Map that's fast enough to be useful. The function will be named alterF to match the name of Data.Map.alter. The remaining question is what order the arguments should go in. I had thought to follow those of alter for consistency, giving
alterF :: (Functor f, Ord k) => (Maybe a -> f (Maybe a)) -> k -> Map k a -> f (Map k a)
Edward Kmett thinks the ergonomics of that order are terrible, and
On Sat, May 7, 2016 at 4:45 PM, David Feuer
wrote: prefers to follow lens at, giving
alterF :: (Functor f, Ord k) => k -> (Maybe a -> f (Maybe a)) -> Map k a -> f (Map k a)
How do other people feel about this?
David Feuer
Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

On 7 May 2016 at 20:45, David Feuer
I managed to find an implementation of Control.Lens.At.at for Data.Map that's fast enough to be useful. The function will be named alterF to match the name of Data.Map.alter. The remaining question is what order the arguments should go in. I had thought to follow those of alter for consistency, giving
alterF :: (Functor f, Ord k) => (Maybe a -> f (Maybe a)) -> k -> Map k a -> f (Map k a)
I would vote for this order. The other order would be very surprising for anyone who is familiar with other functions of this family. Also I think this function is something a significant number of people will use directly, not as a lens. alter is the most general way to update the value for a key, and the need for its monadic variant will come up from time to time. At least I wanted this function a few times in the past. Regards, Takano Akio

Wren Romano and I have decided to maintain consistency in the argument
order, even though this is more annoying for people using lens. Thus
alterF :: (Functor f, Ord k) => (Maybe a -> f (Maybe a)) -> k -> Map k
a -> f (Map k a)
and `Control.Lens.At.at` for maps can be implemented as
at = flip Data.Map.Lazy.alterF
Note that Data.Map.Strict will also offer a version of alterF that
forces any values it installs in the map.
On Sat, May 7, 2016 at 4:45 PM, David Feuer
I managed to find an implementation of Control.Lens.At.at for Data.Map that's fast enough to be useful. The function will be named alterF to match the name of Data.Map.alter. The remaining question is what order the arguments should go in. I had thought to follow those of alter for consistency, giving
alterF :: (Functor f, Ord k) => (Maybe a -> f (Maybe a)) -> k -> Map k a -> f (Map k a)
Edward Kmett thinks the ergonomics of that order are terrible, and prefers to follow lens at, giving
alterF :: (Functor f, Ord k) => k -> (Maybe a -> f (Maybe a)) -> Map k a -> f (Map k a)
How do other people feel about this?
David Feuer

Fair enough.
-Edward
On Thu, May 19, 2016 at 8:30 PM, David Feuer
Wren Romano and I have decided to maintain consistency in the argument order, even though this is more annoying for people using lens. Thus
alterF :: (Functor f, Ord k) => (Maybe a -> f (Maybe a)) -> k -> Map k a -> f (Map k a)
and `Control.Lens.At.at` for maps can be implemented as
at = flip Data.Map.Lazy.alterF
Note that Data.Map.Strict will also offer a version of alterF that forces any values it installs in the map.
I managed to find an implementation of Control.Lens.At.at for Data.Map that's fast enough to be useful. The function will be named alterF to match the name of Data.Map.alter. The remaining question is what order the arguments should go in. I had thought to follow those of alter for consistency, giving
alterF :: (Functor f, Ord k) => (Maybe a -> f (Maybe a)) -> k -> Map k a -> f (Map k a)
Edward Kmett thinks the ergonomics of that order are terrible, and
On Sat, May 7, 2016 at 4:45 PM, David Feuer
wrote: prefers to follow lens at, giving
alterF :: (Functor f, Ord k) => k -> (Maybe a -> f (Maybe a)) -> Map k a -> f (Map k a)
How do other people feel about this?
David Feuer
participants (5)
-
Akio Takano
-
David Feuer
-
Edward Kmett
-
Ivan Lazar Miljenovic
-
Jake McArthur