Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't derive Generic for this type?

Compiling this short snippet on GHC 8.6.2:

{-# LANGUAGE DeriveGeneric, PolyKinds #-}
import GHC.Generics

data Foo f
    = FA
    | FB (f (Foo f))
    deriving (Generic, Generic1)

Results in this error:

Can't make a derived instance of ‘Generic1 Foo’:
  Constructor ‘FB’ applies a type to an argument involving the last parameter
                   but the applied type is not of kind * -> *

Is it not possible to derive Generic for such types? Why?

like image 507
yairchu Avatar asked Mar 06 '23 00:03

yairchu


1 Answers

Generic1 Foo can't be derived because Generic1 is meant for types of kind * -> *, not (* -> *) -> *. In principle there could be support for (* -> *) -> * with more constructors in GHC.Generics, but this approach just doesn't scale well (it comes with lots more unintuitive syntactic restrictions, and you will always have the same problem for more complex types).

You can actually do a lot with plain Generic that overlaps with the initially intended use cases for Generic1. Otherwise, you'll need something more powerful than GHC.Generics like, perhaps, the recently released kind-generics (includes links to paper and hackage).

like image 112
Li-yao Xia Avatar answered Mar 11 '23 18:03

Li-yao Xia