[GHC] #15610: GHCi command to list instances a (possibly compound) type belongs to

GHC ghc-devs at haskell.org
Thu Sep 6 14:55:58 UTC 2018


#15610: GHCi command to list instances a (possibly compound) type belongs to
-------------------------------------+-------------------------------------
           Reporter:  Iceland_jack   |             Owner:  (none)
               Type:  feature        |            Status:  new
  request                            |
           Priority:  lowest         |         Milestone:  8.6.1
          Component:  Compiler       |           Version:  8.4.3
           Keywords:                 |  Operating System:  Unknown/Multiple
       Architecture:                 |   Type of failure:  None/Unknown
  Unknown/Multiple                   |
          Test Case:                 |        Blocked By:
           Blocking:                 |   Related Tickets:
Differential Rev(s):                 |         Wiki Page:
-------------------------------------+-------------------------------------
 This command (`:instances`) would be very useful to me (for deriving in
 particular). People on Twitter were digging it, I believe some are
 interested in implementing it

 {{{
 >> import Data.Functor.Sum (Sum)
 >>
 >> :instances Sum [] []
 Eq   a => Eq   (Sum [] [] a)
 Ord  a => Ord  (Sum [] [] a)
 Show a => Show (Sum [] [] a)
 Read a => Read (Sum [] [] a)
 Functor  (Sum [] [])
 Foldable (Sum [] [])
 Eq1      (Sum [] [])
 Ord1     (Sum [] [])
 Show1    (Sum [] [])
 Read1    (Sum [] [])
 FunctorWithIndex     (Either Int Int) (Sum [] [])
 FoldableWithIndex    (Either Int Int) (Sum [] [])
 TraversableWithIndex (Either Int Int) (Sum [] [])
 }}}

 Not a precise algorithm, but the command `:instances <ty>` lists what
 classes `<ty>` is an instance of. This is something I usually do by hand
 and is useful for finding what instances I can expect to derive with
 `-XDerivingVia`:

 {{{#!hs
 data ...
   deriving (???)
     via (F A B)

 -- >> :instances F A B
 -- Cls1 (F A B)
 -- Cls2 (F A B) ..


 data ...
   deriving (Cls1, Cls2, ..)
     via (F A B)
 }}}

 I expect something like `:instances Sum Endo` to return no instances, but
 I currently rely on my own mind to derive a contradiction for each type. I
 would cross-reference `:info Sum`, `:info Endo` which blows up when the
 types are complex and deeply nested.

  partial type signature (`_`):: the command `:instances Either _ Int`
 should match `Eq a => Eq (Either a Int)`

  trace info:: I find it noisy but we can

     {{{
     >> :instances Sum [] []
     ..
     Functor (Sum [] [])    -- (Functor f, Functor g) => Functor (Sum f g)
 -- Defined in ‘Data.Functor.Sum’
     ..
     }}}

     This would be more natural in a interactive environment where we can
 toggle/expand and collapse it.

  negative results:: There is a `.. => Comonad (Sum f g)` instance but we
 don't have `Comonad (Sum [] [])` because there is no `Comonad []`. It may
 be valuable to query negative results


     {{{
     >> :noinstance Sum [] []
     NO (instance Comonad (Sum [] [])) because
       NO (instance Comonad [])
     }}}

  multi-parameter type class:: I cheekily listed `FunctorWithIndex` example
 of, I am fine dropping MPTCs but listing `Coercible` instances might be
 useful

     {{{
     >> newtype List_or_List a = L_or_L (Sum [] [] a)
     >>
     >> :instance Sum [] []
     ..
     Coercible (Sum [] [] a) (List_or_List a)
     }}}

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


More information about the ghc-tickets mailing list