[GHC] #13465: Foldable deriving treatment of tuples is too surprising
GHC
ghc-devs at haskell.org
Wed Mar 22 01:10:22 UTC 2017
#13465: Foldable deriving treatment of tuples is too surprising
-------------------------------------+-------------------------------------
Reporter: dfeuer | Owner: (none)
Type: bug | Status: new
Priority: normal | Milestone: 8.4.1
Component: Compiler | Version: 8.1
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: Other | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Changes (by RyanGlScott):
* cc: twanvl (added)
Comment:
Ick. This is an eccentricity of
`DeriveFunctor`/`DeriveFoldable`/`DeriveTraversable` that I've never been
keen on fixing, but since folks are complaining about it, I suppose it
should at least be addressed.
It's a somewhat obscure piece of GHC trivia that `DeriveFunctor` //et
al.// special-cases two type constructors:
1. `(->)`
2. Tuples
The `(->)` special case is somewhat justifiable, as it's quite common to
define `Functor` instances where the type parameter occurs to the left of
an arrow. The tuples special-casing is more confusing to me, as I'm not
sure what practical purpose it serves. I've cc'd twanvl, the original
author of these `deriving` extensions, in case he can share some insight
on why he chose to implement it that way.
I too think the Right Thing™ to do here is to change the behavior so that
we just call `fmap`/`foldMap`/`traverse` on occurrences of tuple types,
and reject things like `data Foo a = Foo (a, a) deriving (Functor,
Foldable, Traversable)`. But there's one thorny corner case to watch out
for: unboxed tuples. An even more obscure piece of GHC trivia is that you
can do this:
{{{#!hs
data Foo a = Foo (# a, a #) deriving (Functor, Foldable)
}}}
This is only possible because of special-casing, as calling
`fmap`/`foldMap` on an entire unboxed tuple is ill-kinded (unless we were
to adopt [https://ghc.haskell.org/trac/ghc/ticket/12708 levity-polymorphic
versions] of `Functor` and `Foldable`, I suppose). Moreover, it would feel
weird to allow `data Foo a = Foo (# a, a #)` but not `data Foo a = Foo (a,
a)`. I suppose we could tweak the special-casing so that we reject unboxed
tuples where the type parameter occurs somewhere other than the last
field, which would at least make its behavior consistent with that of
boxed tuples.
But the biggest roadblock by far is that this would (1) make fewer
programs compile than before, and (2) change the behavior of existing
programs. I think we should definitely get some kind of community
consensus (i.e., a GHC proposal) before marching forth with this, although
I have a funny feeling that discussing the behavior of `deriving Foldable`
on tuple types is not going to go well...
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13465#comment:3>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list