Deriving Typeable and Data for GADTs?

348 Views Asked by At

Using:

{-# LANGUAGE GADTs #-}                                                                                                                                                                                                                       
{-# LANGUAGE StandaloneDeriving #-}                                                                                                                                                                                                          
{-# LANGUAGE DeriveDataTypeable #-} 

And given the following datatype:

data Event a where                                                                                                                                                                                                                           
    PureE  :: a                   -> Event a                                                                                                                                                                                                 
    MapE   :: (a -> b) -> Event a -> Event b                                                                                                                                                                                                 

deriving instance Typeable Event                                                                                                                                                                                                             
deriving instance Data a => Data (Event a)  

My goal is to use the uniplate package which requires the Data instance.

Is GHC able to derive Typeable and Data automatically? Since 7.8 GHC should be able to do so and afaik at least for Typeable it is mandatory.

I could probably write my own Data instance ... but why do if GHC can just derive it for me?

1

There are 1 best solutions below

0
On

This seems to work with GHC 8.10.7:

{-# LANGUAGE GADTs #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE DeriveDataTypeable #-}

import Data.Data

data Event a where
    PureE  :: a                   -> Event a
    MapE   :: (a -> b) -> Event a -> Event b

deriving instance Typeable Event
deriving instance (forall b. Data b) => Data (Event a)

The trick is the quantified constraint (forall b. Data b) => ..., which allows GHC to instantiate Data b for any type b on-demand. It's like a "local instance declaration."