content: {-# 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
  
  
  