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

GHC ghc-devs at haskell.org
Thu Sep 6 19:53:22 UTC 2018


#15610: GHCi command to list instances a (possibly compound) type belongs to
-------------------------------------+-------------------------------------
        Reporter:  Iceland_jack      |                Owner:  (none)
            Type:  feature request   |               Status:  new
        Priority:  lowest            |            Milestone:
       Component:  Compiler          |              Version:
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:  #15613            |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------
Changes (by Iceland_jack):

 * version:  8.4.3 =>
 * related:   => #15613
 * milestone:  8.6.1 =>


Old description:

> 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, we can also consider special
> constraints like `Coercible`
>
>     {{{
>     >> newtype List_or_List a = L_or_L (Sum [] [] a)
>     >>
>     >> :instance Sum [] []
>     ..
>     Coercible (Sum [] [] a) (List_or_List a)
>     }}}

New description:

 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 (see #15613 for what might appear as we
 expand instances).

  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, we can also consider special constraints
 like `Coercible`

     {{{
     >> 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#comment:3>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list