Proposal: Add conspicuously missing Functor instances for tuples

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
180 messages Options
1234 ... 9
Reply | Threaded
Open this post in threaded view
|

Proposal: Add conspicuously missing Functor instances for tuples

David Feuer
For some reason I really can't imagine, it seems the only tuple type
with a Functor instance is (,) a. I was astonished to find that

fmap (+1) (1,2,3)

doesn't work. Since this is *useful*, and there is *only one way to do
it*, I propose we add the following:

instance Functor ((,,) a b) where
  fmap f (a,b,c) = (a,b,f c)
instance Functor ((,,,) a b c) where
  fmap f (a,b,c,d) = (a,b,c,f d)
etc.

I would really love to see these make 8.0.0, but if that's impossible
then so be it.
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add conspicuously missing Functor instances for tuples

Ryan Scott
Strong +1 from me. We derive Eq/Ord/Read/Show/etc. for all tuple types
of size up to 15 as it is, we might as well do the same for Functor.

(Personally, I'd even argue for adding Foldable and Traversable
instances as well, but the Foldable instance for pairs has proven to
be pretty controversial...)

Ryan S.
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add conspicuously missing Functor instances for tuples

David Feuer
I'd be strongly +1 on that too! Traversable is strong magic.

On Mon, Jan 18, 2016 at 3:16 PM, Ryan Scott <[hidden email]> wrote:

> Strong +1 from me. We derive Eq/Ord/Read/Show/etc. for all tuple types
> of size up to 15 as it is, we might as well do the same for Functor.
>
> (Personally, I'd even argue for adding Foldable and Traversable
> instances as well, but the Foldable instance for pairs has proven to
> be pretty controversial...)
>
> Ryan S.
> _______________________________________________
> Libraries mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add conspicuously missing Functor instances for tuples

Henning Thielemann

On Mon, 18 Jan 2016, David Feuer wrote:

> I'd be strongly +1 on that too! Traversable is strong magic.

I am opposed to all these Functor, Foldable, Traversable stuff on tuples
(including pairs). Why should the last element of a tuple get a special
treatment? I suspect that if you use such instances you are making
something dirty. I am afraid that those instance may hide type errors or
make type errors incomprehensible. E.g. if you get a stack of fmap's
wrong, you do not get a "no instance for Functor ((,) a)" but instead the
type mismatch occurs at a different level.

I would never use such an instance. Can I be warned if I accidentally use
it anyway?
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add conspicuously missing Functor instances for tuples

David Feuer
Actually, I currently get a much worse error message:

Prelude> fmap (+1) (1,2,3)

<interactive>:2:1:
    Non type-variable argument in the constraint: Functor ((,,) t t)
    (Use FlexibleContexts to permit this)
    When checking that ‘it’ has the inferred type
      it :: forall b t t1.
            (Functor ((,,) t t1), Num b, Num t, Num t1) =>
            (t, t1, b)

That there is a *lousy* error message.

I understand that there are newcomers who struggle to understand the
difference between tuples and lists; I don't think that's a good
enough reason to omit a good and valid instance.

On Mon, Jan 18, 2016 at 3:32 PM, Henning Thielemann
<[hidden email]> wrote:

>
> On Mon, 18 Jan 2016, David Feuer wrote:
>
>> I'd be strongly +1 on that too! Traversable is strong magic.
>
>
> I am opposed to all these Functor, Foldable, Traversable stuff on tuples
> (including pairs). Why should the last element of a tuple get a special
> treatment? I suspect that if you use such instances you are making something
> dirty. I am afraid that those instance may hide type errors or make type
> errors incomprehensible. E.g. if you get a stack of fmap's wrong, you do not
> get a "no instance for Functor ((,) a)" but instead the type mismatch occurs
> at a different level.
>
> I would never use such an instance. Can I be warned if I accidentally use it
> anyway?
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add conspicuously missing Functor instances for tuples

Henning Thielemann

On Mon, 18 Jan 2016, David Feuer wrote:

> Actually, I currently get a much worse error message:
>
> Prelude> fmap (+1) (1,2,3)
>
> <interactive>:2:1:
>    Non type-variable argument in the constraint: Functor ((,,) t t)
>    (Use FlexibleContexts to permit this)
>    When checking that ‘it’ has the inferred type
>      it :: forall b t t1.
>            (Functor ((,,) t t1), Num b, Num t, Num t1) =>
>            (t, t1, b)
>
> That there is a *lousy* error message.
indeed


> I understand that there are newcomers who struggle to understand the
> difference between tuples and lists; I don't think that's a good
> enough reason to omit a good and valid instance.

I would not qualify myself as a newcomer. For me these instances are a
problem, not a help.
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add conspicuously missing Functor instances for tuples

Christopher Allen
I've addressed this here:


The thousand-papercuts opposition to typeclass instances on the premise that a Functor for (a, b, c) maps over the final type not making sense is a rejection of how higher kinded types and typeclasses work together. This is natural and predictable if one bothers to explain it.


On Mon, Jan 18, 2016 at 2:42 PM, Henning Thielemann <[hidden email]> wrote:

On Mon, 18 Jan 2016, David Feuer wrote:

Actually, I currently get a much worse error message:

Prelude> fmap (+1) (1,2,3)

<interactive>:2:1:
   Non type-variable argument in the constraint: Functor ((,,) t t)
   (Use FlexibleContexts to permit this)
   When checking that ‘it’ has the inferred type
     it :: forall b t t1.
           (Functor ((,,) t t1), Num b, Num t, Num t1) =>
           (t, t1, b)

That there is a *lousy* error message.

indeed


I understand that there are newcomers who struggle to understand the
difference between tuples and lists; I don't think that's a good
enough reason to omit a good and valid instance.

I would not qualify myself as a newcomer. For me these instances are a problem, not a help.
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries




--
Chris Allen
Currently working on http://haskellbook.com

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

Re: Proposal: Add conspicuously missing Functor instances for tuples

Ryan Scott
A surprising amount has already been written on the topic of
Functor/Foldable/Traversable instances (both for and against) for
tuples, so I feel it's fair to link them here:

* FTP dangers: http://nattermorphisms.blogspot.com/2015/02/ftp-dangers.html
* Either and (,) in Haskell are not arbitrary:
http://bitemyapp.com/posts/2015-10-19-either-is-not-arbitrary.html
* Foldable for non-Haskellers: Haskell's controversial FTP proposal:
http://tojans.me/blog/2015/10/13/foldable-for-non-haskellers-haskells-controversial-ftp-proposal/#update:916dcbca10117e99a7571170d02b3db4
* The Not-A-Wat in Haskell:
https://www.youtube.com/watch?v=87re_yIQMDw&feature=youtu.be

Ryan S.

On Mon, Jan 18, 2016 at 3:44 PM, Christopher Allen <[hidden email]> wrote:

> I've addressed this here:
>
> http://bitemyapp.com/posts/2015-10-19-either-is-not-arbitrary.html
>
> The thousand-papercuts opposition to typeclass instances on the premise that
> a Functor for (a, b, c) maps over the final type not making sense is a
> rejection of how higher kinded types and typeclasses work together. This is
> natural and predictable if one bothers to explain it.
>
>
> On Mon, Jan 18, 2016 at 2:42 PM, Henning Thielemann
> <[hidden email]> wrote:
>>
>>
>> On Mon, 18 Jan 2016, David Feuer wrote:
>>
>>> Actually, I currently get a much worse error message:
>>>
>>> Prelude> fmap (+1) (1,2,3)
>>>
>>> <interactive>:2:1:
>>>    Non type-variable argument in the constraint: Functor ((,,) t t)
>>>    (Use FlexibleContexts to permit this)
>>>    When checking that ‘it’ has the inferred type
>>>      it :: forall b t t1.
>>>            (Functor ((,,) t t1), Num b, Num t, Num t1) =>
>>>            (t, t1, b)
>>>
>>> That there is a *lousy* error message.
>>
>>
>> indeed
>>
>>
>>> I understand that there are newcomers who struggle to understand the
>>> difference between tuples and lists; I don't think that's a good
>>> enough reason to omit a good and valid instance.
>>
>>
>> I would not qualify myself as a newcomer. For me these instances are a
>> problem, not a help.
>> _______________________________________________
>> Libraries mailing list
>> [hidden email]
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>>
>
>
>
> --
> Chris Allen
> Currently working on http://haskellbook.com
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add conspicuously missing Functor instances for tuples

John Wiegley-2
In reply to this post by Henning Thielemann
>>>>> Henning Thielemann <[hidden email]> writes:

> I would never use such an instance. Can I be warned if I accidentally use it
> anyway?

I don't know why "I wouldn't use it" should extend to "it shouldn't exist".

+1 on having such instances.

--
John Wiegley                  GPG fingerprint = 4710 CF98 AF9B 327B B80F
http://newartisans.com                          60E1 46C4 BD1A 7AC1 4BA2
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add conspicuously missing Functor instances for tuples

Eric Seidel-3
In reply to this post by Christopher Allen
On Mon, Jan 18, 2016, at 12:44, Christopher Allen wrote:
> I've addressed this here:
>
> http://bitemyapp.com/posts/2015-10-19-either-is-not-arbitrary.html
>
> The thousand-papercuts opposition to typeclass instances on the premise
> that a Functor for (a, b, c) maps over the final type not making sense is a
> rejection of how higher kinded types and typeclasses work together. This
> is natural and predictable if one bothers to explain it.

The behavior is indeed predictable, but I think Henning is arguing (and
I would agree) that it is *undesirable*.

That being said, I think the ship has sailed on the "should tuples be a
Functor/etc" discussion. The current proposal is aimed at making the set
of available instances more consistent across tuples, which I'd argue is
a good thing regardless of one's position on the specific class.
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add conspicuously missing Functor instances for tuples

amindfv
I share Henning's concerns. Can someone provide a realistic example of where an instance for (,,) or (,,,) *is* desirable?

Tom


> El 18 ene 2016, a las 15:59, Eric Seidel <[hidden email]> escribió:
>
>> On Mon, Jan 18, 2016, at 12:44, Christopher Allen wrote:
>> I've addressed this here:
>>
>> http://bitemyapp.com/posts/2015-10-19-either-is-not-arbitrary.html
>>
>> The thousand-papercuts opposition to typeclass instances on the premise
>> that a Functor for (a, b, c) maps over the final type not making sense is a
>> rejection of how higher kinded types and typeclasses work together. This
>> is natural and predictable if one bothers to explain it.
>
> The behavior is indeed predictable, but I think Henning is arguing (and
> I would agree) that it is *undesirable*.
>
> That being said, I think the ship has sailed on the "should tuples be a
> Functor/etc" discussion. The current proposal is aimed at making the set
> of available instances more consistent across tuples, which I'd argue is
> a good thing regardless of one's position on the specific class.
> _______________________________________________
> Libraries mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add conspicuously missing Functor instances for tuples

Tikhon Jelvis
In reply to this post by Eric Seidel-3
> I don't know why "I wouldn't use it" should extend to "it shouldn't exist".

I'm in favor of these instances, if only for the sake of consistency. However, I don't agree with this reasoning. Typeclass instances in Haskell are an inherently global construct: once an instance is defined, you can't do anything about it. You can't replace it or redefine it or even not import it. At the same time, it affects type inference and type error messages even if you're *not* using it.

As a slightly more extreme example, there's a reason we don't have a Num instance for functions or Applicatives by default: while perfectly well-formed and even useful, having these instances would lead to worse error messages or even code typechecking when it shouldn't with weird results—even if you never rely on them yourself.

On Mon, Jan 18, 2016 at 12:59 PM, Eric Seidel <[hidden email]> wrote:
On Mon, Jan 18, 2016, at 12:44, Christopher Allen wrote:
> I've addressed this here:
>
> http://bitemyapp.com/posts/2015-10-19-either-is-not-arbitrary.html
>
> The thousand-papercuts opposition to typeclass instances on the premise
> that a Functor for (a, b, c) maps over the final type not making sense is a
> rejection of how higher kinded types and typeclasses work together. This
> is natural and predictable if one bothers to explain it.

The behavior is indeed predictable, but I think Henning is arguing (and
I would agree) that it is *undesirable*.

That being said, I think the ship has sailed on the "should tuples be a
Functor/etc" discussion. The current proposal is aimed at making the set
of available instances more consistent across tuples, which I'd argue is
a good thing regardless of one's position on the specific class.
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


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

Re: Proposal: Add conspicuously missing Functor instances for tuples

Henning Thielemann
In reply to this post by John Wiegley-2

On Mon, 18 Jan 2016, John Wiegley wrote:

>>>>>> Henning Thielemann <[hidden email]> writes:
>
>> I would never use such an instance. Can I be warned if I accidentally use it
>> anyway?
>
> I don't know why "I wouldn't use it" should extend to "it shouldn't exist".

Because I cannot turn it off and I cannot get warning. It is inserted by
GHC whenever it matches, even if I made a mistake when programming.
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add conspicuously missing Functor instances for tuples

Ryan Scott
I can sympathize with your sentiment. Normally, if there's a datatype
whose instance I don't want to use, I just make my own replacement.
However, it's hard to do that with tuples given their special
syntactic treatment.

It might be worth looking into adding RebindableSyntax for tuples [1]
to address scenarios like this.

Ryan S.
-----
[1] https://ghc.haskell.org/trac/ghc/ticket/7845

On Mon, Jan 18, 2016 at 4:22 PM, Henning Thielemann
<[hidden email]> wrote:

>
> On Mon, 18 Jan 2016, John Wiegley wrote:
>
>>>>>>> Henning Thielemann <[hidden email]> writes:
>>
>>
>>> I would never use such an instance. Can I be warned if I accidentally use
>>> it
>>> anyway?
>>
>>
>> I don't know why "I wouldn't use it" should extend to "it shouldn't
>> exist".
>
>
> Because I cannot turn it off and I cannot get warning. It is inserted by GHC
> whenever it matches, even if I made a mistake when programming.
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add conspicuously missing Functor instances for tuples

Eric Seidel-3
In reply to this post by Henning Thielemann
On Mon, Jan 18, 2016, at 13:22, Henning Thielemann wrote:

>
> On Mon, 18 Jan 2016, John Wiegley wrote:
>
> >>>>>> Henning Thielemann <[hidden email]> writes:
> >
> >> I would never use such an instance. Can I be warned if I accidentally use it
> >> anyway?
> >
> > I don't know why "I wouldn't use it" should extend to "it shouldn't exist".
>
> Because I cannot turn it off and I cannot get warning. It is inserted by
> GHC whenever it matches, even if I made a mistake when programming.

There may be an easier way, but one could write a Core-to-Core plugin
that kills the build if it sees an expression like `fmap @(,)`.
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add conspicuously missing Functor instances for tuples

Ryan Scott
In reply to this post by David Feuer
Edward Kmett outlines his reasons why he finds instances for (,)
useful here: https://www.reddit.com/r/haskell/comments/3pfg7x/either_and_in_haskell_are_not_arbitrary/cw65ck2

Speaking for myself, I find the Traversable instance for (,)
incredibly useful. It's quite nice to build up a list of results
alongside a state (i.e, (state, [result]) ), and then traverse over
each of the results such that the new results each have their own copy
of the state (i.e., [(state, result)] ). That kind of patterns arises
quite often in lensy code, and the Traversable instance for (,) is
perfect for the job.

Right now, if you want to have two different states, you have to
employ a kludge (something like ((state1, state2), [result]) ) to get
around the fact that there's no Traversable instance for (,,), (,,,),
etc.

Ryan S.
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add conspicuously missing Functor instances for tuples

John Wiegley-2
In reply to this post by Henning Thielemann
>>>>> Henning Thielemann <[hidden email]> writes:

> Because I cannot turn it off and I cannot get warning. It is inserted by GHC
> whenever it matches, even if I made a mistake when programming.

OK, that's a pretty sound argument against, since this could affect everyone
everywhere, and not just those who opt-in.

--
John Wiegley                  GPG fingerprint = 4710 CF98 AF9B 327B B80F
http://newartisans.com                          60E1 46C4 BD1A 7AC1 4BA2
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add conspicuously missing Functor instances for tuples

Henning Thielemann
In reply to this post by Ryan Scott

On Mon, 18 Jan 2016, Ryan Scott wrote:

> Edward Kmett outlines his reasons why he finds instances for (,)
> useful here: https://www.reddit.com/r/haskell/comments/3pfg7x/either_and_in_haskell_are_not_arbitrary/cw65ck2
>
> Speaking for myself, I find the Traversable instance for (,)
> incredibly useful. It's quite nice to build up a list of results
> alongside a state (i.e, (state, [result]) ), and then traverse over
> each of the results such that the new results each have their own copy
> of the state (i.e., [(state, result)] ). That kind of patterns arises
> quite often in lensy code, and the Traversable instance for (,) is
> perfect for the job.

Sounds like a nice application of the Writer monad, doesn't it?
"Writer" would be much more explicit about what you want to achieve.
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add conspicuously missing Functor instances for tuples

Ryan Scott
WriterT (and Writer) don't quite capture what I need. With WriterT,
you have to tack on that extra m type parameter, and when you just
specialize it to Identity, it only serves as an extra hoop to jump
through to dig out the state. The prescence of the m type parameter
also prevents me from easily modifying the state with a Bifunctor
instance, whereas tuples have no such obstacle.

It's a minor difference, but an important one when I decide which data
structure to reach for.

Ryan S.
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Add conspicuously missing Functor instances for tuples

Henning Thielemann

On Mon, 18 Jan 2016, Ryan Scott wrote:

> WriterT (and Writer) don't quite capture what I need. With WriterT,
> you have to tack on that extra m type parameter, and when you just
> specialize it to Identity, it only serves as an extra hoop to jump
> through to dig out the state. The prescence of the m type parameter
> also prevents me from easily modifying the state with a Bifunctor
> instance, whereas tuples have no such obstacle.

Is it important to achieve this with Bifunctor functions? You could write
a state changing function, or add it to 'transformers', or define your own
Writer as an independent type like it was in mtl initially.

> It's a minor difference, but an important one when I decide which data
> structure to reach for.

Sure, but if you want a certain behaviour then a custom type is better
than putting so much overloading to a standard (tuple) type, isn't it?
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
1234 ... 9