{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TypeFamilies #-} {-# OPTIONS_GHC -fno-warn-redundant-constraints #-} {-# OPTIONS_GHC -fplugin Data.Constraint.Deriving #-} {-# OPTIONS_GHC -fplugin-opt Data.Constraint.Deriving:dump-instances #-} module Spec.DeriveAll02 where import Data.Constraint.Deriving data FooData a b c = FooDataCon Float b deriving (Eq, Ord) instance (a ~ Int, Show b) => Show (FooData a b c) where show (FooDataCon f b) = "FooDataCon " ++ show f ++ " " ++ show b type family FooFam a b c d e f type instance FooFam a b c Double e f = FooData Int b c class Ord b => FooClass a b c where fooFun :: a -> b -> c barFun :: a -> c -> b instance (a ~ Int, Ord b, Show a) => FooClass (FooData a b c) b Float where fooFun (FooDataCon f _) _ = f barFun (FooDataCon _ b) _ = b {-# ANN type BazTy DeriveAll #-} newtype BazTy a b c d e f = BazCon (FooFam a b c d e f) -- Type class constraints are prepended to the instance arguments. -- Thus, they can be used to impose additional (fictional) constraints -- on the generated instances. type instance DeriveContext (BazTy a b c d e f ) = Show e