## GHCi command to list instances a (possibly compound) type belongs to

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`

:

```
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) `