Proposal: Add bifunctor related classes to base

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
17 messages Options
Reply | Threaded
Open this post in threaded view
|

Proposal: Add bifunctor related classes to base

Dan Doel
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

_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add bifunctor related classes to base

Niklas Haas
On Fri, 25 Apr 2014 12:02:33 -0400, Dan Doel <[hidden email]> 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.
_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add bifunctor related classes to base

Nathan Bouscal
+1


On Fri, Apr 25, 2014 at 12:14 PM, Niklas Haas <[hidden email]> wrote:
On Fri, 25 Apr 2014 12:02:33 -0400, Dan Doel <[hidden email]> 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.
_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries


_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add bifunctor related classes to base

Carter Schonwald
+1 


On Fri, Apr 25, 2014 at 12:18 PM, Nathan Bouscal <[hidden email]> wrote:
+1


On Fri, Apr 25, 2014 at 12:14 PM, Niklas Haas <[hidden email]> wrote:
On Fri, 25 Apr 2014 12:02:33 -0400, Dan Doel <[hidden email]> 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.
_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries


_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries



_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add bifunctor related classes to base

Casey McCann-2
In reply to this post by Dan Doel
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 <[hidden email]> 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
>
> _______________________________________________
> Libraries mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/libraries
>
_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add bifunctor related classes to base

Edward Kmett-2
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 <[hidden email]> 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 <[hidden email]> 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
>>
>> _______________________________________________
>> Libraries mailing list
>> [hidden email]
>> http://www.haskell.org/mailman/listinfo/libraries
> _______________________________________________
> Libraries mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/libraries
_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add bifunctor related classes to base

Andreas Abel
-----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
>> <[hidden email]> 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 <[hidden email]>
>>> 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

[hidden email]
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-----
_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add bifunctor related classes to base

Dominique Devriese-2
In reply to this post by Dan Doel
+1

Regards
Dominique

2014-04-25 18:02 GMT+02:00 Dan Doel <[hidden email]>:

> 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
>
> _______________________________________________
> Libraries mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/libraries
>
_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add bifunctor related classes to base

Edward Kmett-2
In reply to this post by Andreas Abel
for :: (Traversable t, Applicative f) => t a -> (a -> f b) -> f (t b)

Unfortunate or not, bifor follows the existing convention from Traversable in base.

Given two candidate conventions, I'd choose to err on the side of what we are already doing elsewhere in the library rather than devise and explain a new convention for little margin gain and much added confusion, while simultaneously hitting existing users with type errors / semantics changes.











On Fri, Apr 25, 2014 at 1:14 PM, Andreas Abel <[hidden email]> wrote:
-----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 <a href="tel:25.04.2014%2018" value="+12504201418">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
>> <[hidden email]> 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 <[hidden email]>
>>> 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

[hidden email]
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-----


_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add bifunctor related classes to base

Dan Doel
In reply to this post by Andreas Abel
On Fri, Apr 25, 2014 at 1:14 PM, Andreas Abel <[hidden email]> wrote:
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

​These definitions make no sense to me. flip bimap and flip bitraverse just swap the order of the traversal functions passed in.​ Their definition in bifunctors actually moves the structure to the first argument, which is the actual point of for(M).

Unfortunately, "for" was taken for "flip traverse" by
Data.Traversable.  Instead "forA" should have been used.

​I don't find this to be unfortunate at all. Sorry. for is useful, and forA is a worse name (as is forM). Especially as we'll be able to get rid of sequenceA (and thus bisequenceA) in 7.10 with the improved hierarchy, leaving no -A functions aside from liftAN. I don't know if we will do that, but it's _not_ the convention to name these functions fooA. And I'm not in favor of making it the convention, either.

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.)

​And in base we don't do that.​

​In my code, I use (<&>) from lens when I need a flipped fmap:

    let ys = xs <&> \x -> ...

and do use Applicative for.

Proposal:  use "biforA" instead of "bifor".

​Negative.


_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add bifunctor related classes to base

Herbert Valerio Riedel
In reply to this post by Dan Doel
On 2014-04-25 at 18:02:33 +0200, Dan Doel 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.

[...]

+1 !
_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add bifunctor related classes to base

Anthony Cowley
In reply to this post by Dan Doel
+1



On Fri, Apr 25, 2014 at 12:02 PM, Dan Doel <[hidden email]> 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
>
> _______________________________________________
> Libraries mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/libraries
>
_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add bifunctor related classes to base

Oliver Charles-3
In reply to this post by Dan Doel
While I can't say I've ever reached for Bi* type classes, the argument to move people away from Control.Arrow for what is generally Either-specific functionality is a strong one. Furthermore, this stuff seems quite common (I've seen bifunctors come up in a few papers now).

+1!

- ocharles


On Fri, Apr 25, 2014 at 5:02 PM, Dan Doel <[hidden email]> 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

_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries



_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add bifunctor related classes to base

Andreas Abel
In reply to this post by Dan Doel
I retract my bikeshedding attempt.

On 25.04.14 8:18 PM, Dan Doel wrote:
> ​In my code, I use (<&>) from lens when I need a flipped fmap:
>
>      let ys = xs <&> \x -> ...
>
> and do use Applicative for.

Maybe & and <&> become standard at some point, and then I am maybe fine
to use them.  Only that "<&>", unlike "for", does not evoke any
association to iteration in my brain.

--
Andreas Abel  <><      Du bist der geliebte Mensch.

[hidden email]
http://www2.tcs.ifi.lmu.de/~abel/
_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add bifunctor related classes to base

João Cristóvão
> The previous discussion about methods on Either had some mention of adding bifunctors to base, but no one wrote up the details

I was implicitly leaving that to someone more qualified than me ;)

This proposal looks great to me, and I agree that it is the right abstraction for functions like mapLeft and such, instead of Arrows.
Still, some of the underlying assumptions made are not entirely clear to me:

> 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.

So, what you are proposing is that mapLeft and such are _not_ standalone functions in Data.Either, but instead we just add documentation refering them to bifunctors as the correct abstraction, a merge of my "Proposal 1" with "Proposal 8". Although I'm much more confortable with this than forwarding user to arrows, I still see a point in adding this basic functions in Data.Either.

It is my understanding that Data.List has a very complete API mainly for historical reasons, and that nowadays it is recomended to use Foldable and Traversable for many of those operations. The same applies to Data.Maybe. But a novice user will then look at Data.Either and Data.Tuple, and think: are these second class citizens?
I guess this is an entirely different discussion, that happend many times in the past with no relevant consensus...

An additional question: would the arrow operators then be defined in terms of bifunctors?

Cheers



2014-04-26 8:31 GMT+01:00 Andreas Abel <[hidden email]>:
I retract my bikeshedding attempt.

On 25.04.14 8:18 PM, Dan Doel wrote:
​In my code, I use (<&>) from lens when I need a flipped fmap:

     let ys = xs <&> \x -> ...

and do use Applicative for.

Maybe & and <&> become standard at some point, and then I am maybe fine to use them.  Only that "<&>", unlike "for", does not evoke any association to iteration in my brain.


--
Andreas Abel  <><      Du bist der geliebte Mensch.

[hidden email]
http://www2.tcs.ifi.lmu.de/~abel/

_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries


_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add bifunctor related classes to base

Edward Kmett-2
On Mon, Apr 28, 2014 at 6:28 AM, João Cristóvão <[hidden email]> wrote:
> The previous discussion about methods on Either had some mention of adding bifunctors to base, but no one wrote up the details

I was implicitly leaving that to someone more qualified than me ;)

This proposal looks great to me, and I agree that it is the right abstraction for functions like mapLeft and such, instead of Arrows.
 
Still, some of the underlying assumptions made are not entirely clear to me:

> 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.

I'm perfectly happy to say we should go through and put in documentation in Data.Either and Data.Maybe talking about how they can be used with the respective Data.Bifunctor and Control.Arrow combinators. That seems like an obvious win with no downside.

So, what you are proposing is that mapLeft and such are _not_ standalone functions in Data.Either, but instead we just add documentation refering them to bifunctors as the correct abstraction, a merge of my "Proposal 1" with "Proposal 8". Although I'm much more confortable with this than forwarding user to arrows, I still see a point in adding this basic functions in Data.Either.

I think it is worth voting on this independently of the Data.Either additions, and would support adding the bifunctors machinery regardless of what we do with Data.Either.
 
It is my understanding that Data.List has a very complete API mainly for historical reasons, and that nowadays it is recomended to use Foldable and Traversable for many of those operations. The same applies to Data.Maybe. But a novice user will then look at Data.Either and Data.Tuple, and think: are these second class citizens?
I guess this is an entirely different discussion, that happend many times in the past with no relevant consensus...

The fact that "lists get their own special API" is really the exception not the rule in base. 

In fact, many types exported from Data.List will actually be generalizing to avoid creating dozens of import conflicts with the Prelude as part of the 7.10 transition. So pointing there to say here is an example of something more monomorphic example than elsewhere is a bad idea.

I'm not in a hurry to see a huge proliferation of names for one-off purposes.

That leaves me personally rather -1 on the majority of the Data.Either proposal.

An additional question: would the arrow operators then be defined in terms of bifunctors?

The arrow combinators and the bifunctor combinators are not definable in terms of one another except in special cases.
 
-Edward

_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add bifunctor related classes to base

John Wiegley-2
In reply to this post by Oliver Charles-3
>>>>> Oliver Charles <[hidden email]> writes:

> While I can't say I've ever reached for Bi* type classes, the argument to
> move people away from Control.Arrow for what is generally Either-specific
> functionality is a strong one. Furthermore, this stuff seems quite common
> (I've seen bifunctors come up in a few papers now).

> +1!

+1

John
_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries