Opened 2 years ago

Last modified 13 months ago

#14146 new feature request

Can GHC propose kind restrictions?

Reported by: Iceland_jack Owned by:
Priority: normal Milestone:
Component: Compiler Version: 8.2.1
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: #13992, #16050 Differential Rev(s):
Wiki Page:

Description (last modified by Iceland_jack)

This is UX. As my code gets more polykinded I find myself in situations such as these all the more often

instance (Comonad f, Representable f, Comonad g, Representable g) => Comonad (Compose f g) where
  extract   = undefined 
  duplicate = undefined 

instance ComonadApply (Compose f g) where
  (<@>) = undefined 
/tmp/a.hs:20:10-35: error:
       • No instance for (Comonad (Compose f g))
           arising from the superclasses of an instance declaration
       • In the instance declaration for ‘ComonadApply (Compose f g)’
      |
   20 | instance ComonadApply (Compose f g) where
      |          ^^^^^^^^^^^^^^^^^^^^^^^^^^
   Failed, modules loaded: none.

It would help me if GHC looked up a Comonad (Compose _ _) instance, compared the kinds

Comonad      (Compose (f :: Type -> Type) (g :: Type -> Type) :: Type -> Type)
ComonadApply (Compose (f :: k    -> Type) (g :: Type -> k)    :: Type -> Type)

a simple suggestion like this would be helpful

       • No instance for (Comonad (Compose f g))
           arising from the superclasses of an instance declaration
         Try adding a kind signature (ComonadApply (Compose (f :: Type -> Type) g)).

Even more amazing would be

       • No instance for (Comonad (Compose f g))
           arising from the superclasses of an instance declaration
         Try adding a context
            (Comonad f, Representable f, Comonad g, Representable g) 
              => ComonadApply (Compose f g)

Which the compiler could in theory guess, since following GHC's suggestion iteratively you end up with

ComonadApply (Compose (f :: Type -> Type) g)

-- ==> add (Comonad f) to the context of the instance declaration
Comonad f => ComonadApply (Compose f g)

-- ==> add (Comonad g) to the context of the instance declaration
(Comonad f, Comonad g) => ComonadApply (Compose f g)

-- ==> add (Representable g) to the context of the instance declaration
(Comonad f, Comonad g, Representable g) => ComonadApply (Compose f g)

-- ==> add (Representable f) to the context of the instance declaration
(Comonad f, Comonad g, Representable g, Representable f) => ComonadApply (Compose f g)

Change History (2)

comment:1 Changed 2 years ago by Iceland_jack

Description: modified (diff)

comment:2 Changed 13 months ago by RyanGlScott

Note: See TracTickets for help on using tickets.