[GHC] #13465: Foldable deriving treatment of tuples is too surprising

#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 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: Other Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- {{{ *> :set -XDeriveFoldable *> data Foo a = Foo ((a,a),a) deriving Foldable *> length ((1,1),1) 1 *> length $ Foo ((1,1),1) 3 }}} I think the right thing is probably to refuse to derive `Foldable` if components of a tuple other than the last one may contain the type variable we're looking for. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13465 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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: | -------------------------------------+------------------------------------- Comment (by hvr): Same goes for `-XDeriveFunctor` btw -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13465#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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: | -------------------------------------+------------------------------------- Comment (by dfeuer): Replying to [comment:1 hvr]:
Same goes for `-XDeriveFunctor` btw
`DeriveFunctor` will only surprise by succeeding when might not expect it to; it cannot really have surprising behavior. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13465#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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

#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: | -------------------------------------+------------------------------------- Comment (by RyanGlScott): Sorry, the claim that the behavior of existing programs would change is false—it would only cause some existing programs that currently compile to no longer compile, which I think is acceptable. Also, here's the [https://mail.haskell.org/pipermail/ghc- devs/2017-March/013995.html ghc-devs mailing list] discussion on the matter. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13465#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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: deriving 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): * keywords: => deriving -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13465#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC