Proposal: Add bifunctor related classes to base

Niklas Haas haskell at nand.wakku.to
Fri Apr 25 16:14:34 UTC 2014


On Fri, 25 Apr 2014 12:02:33 -0400, 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.

+1, these are low-cost abstractions that definitely could use some more
exposure and love, and with the 7.10 change in particular moving around
the Applicative/Monad functions either way, it seems like a good time to
refactor the Foldable/Traversable stuff and bring this in.


More information about the Libraries mailing list