[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