Skip to content

GHC can't derive instance of polykinded typeclass for newtype that requires a class constraint

GHC chokes 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

with the following error:

$ /opt/ghc/8.0.1/bin/ghc Example.hs -fprint-explicit-kinds
[1 of 1] Compiling Example          ( Example.hs, Example.o )

Example.hs:9:57: error:
    • No instance for (Category * c)
        arising from the 'deriving' clause of a data type declaration
      Possible fix:
        use a standalone 'deriving instance' declaration,
          so you can specify the instance context yourself
    • When deriving the instance for (Category * (T c))

I know what is happening. Unlike in #8865 (closed), 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.

To fix this behavior, I think we just need to change validDerivPred to only consider the //visible// arguments of Category (i.e., only c). This should be a pretty easy fix - patch incoming.

Trac metadata
Trac field Value
Version 8.0.1
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler (Type checker)
Test case
Differential revisions
BlockedBy
Related #8865 (closed)
Blocking
CC
Operating system
Architecture
Edited by Ryan Scott
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information