Proposal: Add bifunctor related classes to base
Andreas Abel
andreas.abel at ifi.lmu.de
Fri Apr 25 17:14:41 UTC 2014
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
A general +1 from me.
To start the bikeshedding, let's have a look at the names in
Data.Bitraversable:
bitraverse :: Applicative f => (a -> f c) -> (b -> f d) -> t a b -> f
(t c d)
bisequenceA:: Applicative f => t (f a) (f b) -> f (t a b)
bimapM :: Monad m => (a -> m c) -> (b -> m d) -> t a b -> m (t c d)
bisequence :: Monad m => t (m a) (m b) -> m (t a b)
bifor :: (Bitraversable t, Applicative f) => t a b -> (a -> f c) -> (b
- -> f d) -> f (t c d)
biforM :: (Bitraversable t, Monad m) => t a b -> (a -> m c) -> (b -> m
d) -> m (t c d)
I am unhappy about the name "bifor".
forM = flip mapM, so the right generalizations would be
for = flip map
bifor = flip bimap
forA = flip mapA = flip traverse
biforA = flip bimapA = flip bitraverse
Unfortunately, "for" was taken for "flip traverse" by
Data.Traversable. Instead "forA" should have been used.
In my own code, I actually define
for = flip map
and use it in situations like
let ys = for xs $ \ x ->
long
function
body
(I never use "for" from Data.Traversable anyway, since I have not
needed yet an Applicative which is not a Monad.)
Proposal: use "biforA" instead of "bifor".
Cheers,
Andreas
On 25.04.2014 18:36, Edward Kmett wrote:
> Biapplicative is left out because unlike the other two, it is
> underdetermined. There are at least two forms of biapplicative
> point. There are however, no such headaches with
> Bifunctor/Bifoldable/Bitraversable, which get nailed down hard by
> the laws.
>
> A very enthusiastic +1 on the proposal from me.
>
> -Edward
>
>> On Apr 25, 2014, at 12:28 PM, Casey McCann
>> <cam at uptoisomorphism.net> wrote:
>>
>> Was Biapplicative left out of the proposal because of
>> dependencies? It seems at least as useful as the others.
>>
>> - C.
>>
>>> On Fri, Apr 25, 2014 at 12:02 PM, Dan Doel <dan.doel at gmail.com>
>>> wrote: The previous discussion about methods on Either had some
>>> mention of adding bifunctors to base, but no one wrote up the
>>> details. So I've taken it upon myself to do so.
>>>
>>>
>>> The following proposal is to add some modules of the bifunctors
>>> [1] package to base, namely:
>>>
>>> Data.Bifunctor Data.Bifoldable Data.Bitraversable
>>>
>>> These modules contain classes and functions for working with
>>> types similar to those identified by Functor, Foldable and
>>> Traversable, except that there are parameterized by two
>>> 'element types' so to speak.
>>>
>>>
>>> The advantages of this change are among the following:
>>>
>>> These are the right abstractions for many operations. For
>>> instance, Arrow is often recommended if someone wants to map
>>> over both sides (or the left side) of a pair. In fact, I'd
>>> wager that it is the single most common reason for recommending
>>> use of Arrow. But this is not really what Arrow was designed
>>> to accomplish. This is exactly what Bifunctor is for, though,
>>> and it abstracts over this kind of operation with pairs,
>>> Either, and in my experience many custom data types.
>>>
>>> Placement in base gives a better opportunity for people to find
>>> these right abstractions. If someone goes into the
>>> documentation for Data.Either looking for a way to map both
>>> parameters, they will not, of course, be directed to the
>>> bifunctors package, even though it provides a good means of
>>> doing what they want. If Bifunctor were in base, the
>>> documentation for Either would note that it is one.
>>>
>>>
>>> Some things to consider:
>>>
>>> The API of the modules will shrink a bit due to Applicative
>>> becoming a superclass of Monad in 7.10. There is no reason for
>>> a separate bitraverse and bimapM and so on. Some things will
>>> likely be renamed, as well; bisequenceA => bisequence, for
>>> instance.
>>>
>>> The 'first' and 'second' functions in Data.Bifunctor overlap
>>> with Arrow. This actually means that they are a drop-in
>>> replacement for the commonly suggested misuse of Arrow.
>>>
>>> None of the dependencies of the bifunctors package are needed
>>> by the modules in question. They are used for other modules, or
>>> as part of an arbitrary decision of where to put an instance.
>>> For example, the tagged dependency is used to give instances
>>> for Tagged, but these could easily be moved into the tagged
>>> package if base were to adopt these classes.
>>>
>>>
>>> Discussion period: 2 weeks
>>>
>>> [1] http://hackage.haskell.org/package/bifunctors
- --
Andreas Abel <>< Du bist der geliebte Mensch.
Department of Computer Science and Engineering
Chalmers and Gothenburg University, Sweden
andreas.abel at gu.se
http://www2.tcs.ifi.lmu.de/~abel/
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/
iEYEARECAAYFAlNamAEACgkQPMHaDxpUpLM43gCcCZJS6y4OIYtSU+RifojGKLha
C6EAoOQUhUKbJs3Dt9OZ6ryK97cGrCji
=X8HU
-----END PGP SIGNATURE-----
More information about the Libraries
mailing list