    {-# LANGUAGE EmptyDataDecls #-}
    {-# LANGUAGE MultiParamTypeClasses #-}
    {-# LANGUAGE TypeSynonymInstances #-}
    {-# LANGUAGE TypeOperators #-}
    {-# LANGUAGE TypeFamilies #-}
    {-# OPTIONS_GHC -fno-warn-orphans #-}

    module Generics.Deriving.Instances (
    -- Only instances from Generics.Deriving.Base
    -- and the Generic1 instances
    #if __GLASGOW_HASKELL__ < 705
        Rep1Maybe, Rep1List
    #endif
    #if __GLASGOW_HASKELL__ < 701
      -- * Representations for base types
      , Rep0Char, Rep0Int, Rep0Float
      , Rep0Maybe, Rep0List
    #endif
      ) where

    #if __GLASGOW_HASKELL__ < 705
    import Generics.Deriving.Base
    #endif

    #if __GLASGOW_HASKELL__ < 701
    --------------------------------------------------------------------------------
    -- Representation for base types
    --------------------------------------------------------------------------------

    -- Representation types
    {-
    type Rep1Par1 = Par1
    instance Generic1 Par1 Rep1Par1 where
      from1 = id
      to1 = id

    type Rep1Rec1 f = Rec1 f
    instance Generic1 (Rec1 f) (Rep1Rec1 f) where
      from1 = id
      to1 = id
    -}
    -- Kind *

    type Rep0Char = Rec0 Char
    instance Generic Char where
      type Rep Char = Rep0Char
      from = K1
      to = unK1

    type Rep0Int = Rec0 Int
    instance Generic Int where
      type Rep Int = Rep0Int
      from = K1
      to = unK1

    type Rep0Float = Rec0 Float
    instance Generic Float where
      type Rep Float = Rep0Float
      from = K1
      to = unK1

    -- etc...

    -- Kind * -> *

    type Rep0Maybe a = D1 Maybe_ (C1 Nothing_ U1 :+: C1 Just_ (Par0 a))
    instance Generic (Maybe a) where
      type Rep (Maybe a) = Rep0Maybe a
      from Nothing  = M1 (L1 (M1 U1))
      from (Just x) = M1 (R1 (M1 (K1 x)))
      to (M1 (L1 (M1 U1)))     = Nothing
      to (M1 (R1 (M1 (K1 x)))) = Just x

    type Rep0List a = D1 List__ ((C1 Nil__ U1) :+: (C1 Cons__ (Par0 a :*: Rec0 [a])))
    instance Generic [a] where
      type Rep [a] = Rep0List a
      from []    = M1 (L1 (M1 U1))
      from (h:t) = M1 (R1 (M1 (K1 h :*: K1 t)))
      to (M1 (L1 (M1 U1)))              = []
      to (M1 (R1 (M1 (K1 h :*: K1 t)))) = h : t
    #endif

    #if __GLASGOW_HASKELL__ < 705
    -- GHC 7.2 and 7.4 still need these instances; 7.6 doesn't

    data Maybe_
    data Nothing_
    data Just_

    instance Datatype Maybe_ where
      datatypeName _ = "Maybe"
      moduleName   _ = "Representation"

    instance Constructor Nothing_ where
      conName _ = "Nothing"

    instance Constructor Just_ where
      conName _ = "Just"

    type Rep1Maybe = D1 Maybe_ (C1 Nothing_ U1 :+: C1 Just_ Par1)
    instance Generic1 Maybe where
      type Rep1 Maybe = Rep1Maybe
      from1 Nothing  = M1 (L1 (M1 U1))
      from1 (Just x) = M1 (R1 (M1 (Par1 x)))
      to1 (M1 (L1 (M1 U1)))       = Nothing
      to1 (M1 (R1 (M1 (Par1 x)))) = Just x

    data List__
    data Nil__
    data Cons__

    instance Datatype List__ where
      datatypeName _ = "[]"
      moduleName   _ = "Data.List"

    instance Constructor Nil__  where conName _ = "[]"
    instance Constructor Cons__ where
      conName   _ = ":"
      conFixity _ = Infix RightAssociative 5

    type Rep1List = D1 List__ ((C1 Nil__ U1) :+: (C1 Cons__ (Par1 :*: Rec1 [])))
    instance Generic1 [] where
      type Rep1 [] = Rep1List
      from1 []    = M1 (L1 (M1 U1))
      from1 (h:t) = M1 (R1 (M1 (Par1 h :*: Rec1 t)))
      to1 (M1 (L1 (M1 U1)))                  = []
      to1 (M1 (R1 (M1 (Par1 h :*: Rec1 t)))) = h : t

    -- etc...

    #endif