
#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