Make validDerivPred ignore non-visible arguments to a class type constructor

Authored by RyanGlScott on May 2 2016, 11:38 AM.

Description

Make validDerivPred ignore non-visible arguments to a class type constructor

Summary:
GHC choked when trying to derive the following:

{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE PolyKinds #-}
module Example where

class Category (cat :: k -> k -> *) where
  catId   :: cat a a
  catComp :: cat b c -> cat a b -> cat a c

newtype T (c :: * -> * -> *) a b = MkT (c a b) deriving Category

Unlike in Trac #8865, where we were deriving Category for a concrete type like
Either, in the above example we are attempting to derive an instance of the
form:

instance Category * c => Category (T * c) where ...

(using -fprint-explicit-kinds syntax). But validDerivPred is checking if
sizePred (Category * c) equals the number of free type variables in
Category * c. But note that sizePred counts both type variables and
type constructors, and * is a type constructor! So validDerivPred
erroneously rejects the above instance.

The fix is to make validDerivPred ignore non-visible arguments to the class
type constructor (e.g., ignore * is Category * c) by using
filterOutInvisibleTypes.

Fixes Trac #11833.

Test Plan: ./validate

Reviewers: goldfire, hvr, simonpj, austin, bgamari

Reviewed By: bgamari

Subscribers: thomie

Differential Revision: https://phabricator.haskell.org/D2112

GHC Trac Issues: Trac #11833