{- |

   Description : import me
   Copyright   : (C) 2004, Oleg Kiselyov, Ralf Laemmel, Keean Schupke

   The HList library

   This module re-exports everything needed to use HList.

-}

module Data.HList.CommonMain (

   module Data.HList.FakePrelude
 , module Data.HList.HListPrelude
 , module Data.HList.HArray
 , module Data.HList.HOccurs
 , module Data.HList.HTypeIndexed
 , module Data.HList.Record
 , module Data.HList.HList
 , module Data.HList.TypeEqO
 , module Data.HList.TIP
 , module Data.HList.TIC
 , module Data.HList.HZip
 , module Data.HList.Variant

 -- * "Data.HList.Keyword"
 -- | the \"public\" parts. More examples are in the module documentation.
 , Kw(..), recToKW, IsKeyFN, K,  ErrReqdArgNotFound,  ErrUnexpectedKW

 -- * Labels
 {- | there are really only two options for now, but there are
   a couple different styles for the first option here:

   GHC supports type-level strings ('GHC.TypeLits.Symbol'), and these can be
   labels. You can refer to these strings using an unwieldy syntax. For
   example if you want to store a value @5@ in a record @rec@ with a field
   called @\"x\"@, and then get it out again:

   let rec = ('Label' :: Label \"x\") '.=.' 5 '.*.' 'emptyRecord'

   rec '.!.' (Label :: Label \"x\")

   To avoid that pain, you can have a definition @x = Label :: Label "x"@.
   and just use @x@ instead of repeating @Label :: Label \"x\"@ so that
   a lookup becomes:

   > rec .!. x

   See 'makeLabels6' for automating the @x = Label :: Label \"x\"@.

 -}
 -- $label6demo

 , module Data.HList.Labelable
 -- $labelable

 -- ** namespaced labels
 , module Data.HList.Label3

 -- | template haskell for automating different types of labels
 , module Data.HList.MakeLabels
 -- | quasiquoter 'pun' helps to avoid needing a proxy value with
 -- type 'Label' in the first place: when you take values out of or into
 -- records with pattern matching, the variable name determines the label
 -- name.
 , module Data.HList.RecordPuns


 -- * "Data.HList.Data"
 -- | This modules provide useful instances. A useful application can be
 -- found in @examples/cmdargs.hs@
) where

import Data.HList.FakePrelude
import Data.HList.HListPrelude
import Data.HList.HArray
import Data.HList.HOccurs
import Data.HList.HTypeIndexed
import Data.HList.Record
import Data.HList.HList
import Data.HList.MakeLabels
import Data.HList.TypeEqO
import Data.HList.TIP
import Data.HList.TIC

import Data.HList.HZip
import Data.HList.Label3
import Data.HList.Label6 () -- only instances
import Data.HList.Labelable

import Data.HList.Variant

import Data.HList.Data () -- only instances

import Data.HList.Keyword
import Data.HList.RecordPuns

{- $label6demo #label6demo#

 Instances from "Data.HList.Label6"

>>> :set -XDataKinds
>>> (Label :: Label "x") .=. (5::Int) .*. emptyRecord
Record{x=5}

>>> let x = Label :: Label "x"
>>> let r = x .=. (5::Int) .*. emptyRecord
>>> r .!. x
5

-}

{- $labelable #labelabledemo#

Rather than having the @x = Label :: Label \"x\"@, the labels
generated by 'makeLabelable' also double lenses for "Control.Lens".
Here is an example of how much better that is:

>>> :set -XNoMonomorphismRestriction -XDataKinds -XPolyKinds
>>> import Control.Lens
>>> let x = hLens' (Label :: Label "x")

The Label6 method:

>>> let r = (Label :: Label "x") .=. "5" .*. emptyRecord

The Labelable way:

>>> let r2 = x .==. "5" .*. emptyRecord

>>> r ^. x
"5"

>>> r2 ^. x
"5"

>>> r & x .~ ()
Record{x=()}

-}