{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE MultiParamTypeClasses #-} -- Based on https://www.haskell.org/haskellwiki/GHC/Type_families#Detailed_definition_of_data_families module DataFamilies ( GMap , GMapKey(type GMapK) ) where -- Type 1, Top level data family GMap k :: * -> * data family Array e data family ArrayK :: * -> * -- Type 2, associated types class GMapKey k where data GMapK k :: * -> * class C a b c where { data T1 c a :: * } -- OK -- class C a b c where { data T a a :: * } -- Bad: repeated variable -- class D a where { data T a x :: * } -- Bad: x is not a class variable class D a where { data T2 a :: * -> * } -- OK -- Instances data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v) data family T3 a data instance T3 Int = A data instance T3 Char = B nonsense :: T3 a -> Int -- nonsense A = 1 -- WRONG: These two equations together... -- nonsense B = 2 -- ...will produce a type error. nonsense = undefined instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where data GMapK (Either a b) v = GMapEitherK (GMap a v) (GMap b v) -- data GMap () v = GMapUnit (Maybe v) -- deriving Show