[GHC] #10447: DeriveFoldable rejects instances with constraints in last argument of data type

GHC ghc-devs at haskell.org
Thu May 28 02:59:55 UTC 2015


#10447: DeriveFoldable rejects instances with constraints in last argument of data
type
-------------------------------------+-------------------------------------
        Reporter:  RyanGlScott       |                   Owner:
            Type:  bug               |                  Status:  new
        Priority:  normal            |               Milestone:
       Component:  Compiler          |                 Version:  7.10.1
      Resolution:                    |                Keywords:
Operating System:  Unknown/Multiple  |            Architecture:
 Type of failure:  GHC rejects       |  Unknown/Multiple
  valid program                      |               Test Case:
      Blocked By:                    |                Blocking:
 Related Tickets:  #8678             |  Differential Revisions:
-------------------------------------+-------------------------------------

Comment (by RyanGlScott):

 Replying to [comment:10 dolio]:
 > Also, for instance
 >
 > {{{
 >     data Refine a where
 >       RefineI :: Refine Int
 >       RefineD :: Refine Double
 >
 >     data Foo a = Foo (Refine a) Int
 > }}}
 >
 > Should a `Foldable` instance for `Foo` test the `Refine a` and fold over
 the `Int` if it's `RefineI`?

 I assume that {{{Refine}}} is also an instance of {{{Foldable}}}? If so,
 the respective derived {{{Foldable}}} instances of {{{Refine}}} and
 {{{Foo}}} would be:

 {{{#!hs
 instance Foldable Refine where
     foldr f z RefineI = z
     foldr f z RefineD = z
     foldMap f RefineI = mempty
     foldMap f RefineD = mempty

 instance Foldable Foo where
     foldr f z (Foo a1 a2) = foldr f z a1
     foldMap f (Foo a1 a2) = mappend (foldMap f a1) mempty
 }}}

 So no, the derived instance wouldn't fold over the {{{Int}}}, since the
 {{{Foldable Foo}}} instance would never pattern match on a constructor of
 {{{Refine}}}.

 I don't see this as a problem, especially since this seems consistent with
 the behavior of {{{deriving Generic1}}} statements, which also check if a
 field has the same type as the last type parameter. For example, if you
 derived a {{{Generic1}}} instance for {{{Foo}}}, it would give:

 {{{#!hs
 type Rep1 Foo = D1 D1Foo (C1 C1_0Foo (S1 NoSelector (Rec1 Refine)
                                   :*: S1 NoSelector (Rec0 Int)))
 }}}

 So {{{deriving Generic1}}} would also consider the {{{a}}} in {{{Refine
 a}}} to be distinct from {{{Int}}}, as evidenced by their differing
 {{{Rec1}}} and {{{Rec0}}} wrappers.

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10447#comment:11>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list