    {-# LANGUAGE CPP #-}

    -- | Class to provide type-driven access to elements of a HList
    module Data.HList.ContainsType
      ( ContainsType(..)
      )
    where

    import Data.HList.HList

    ----------------------------------------
    -- class ContainsType
    -- | for get/put of a value in a HList, with type-directed lookup.
    class ContainsType a c where
      setHListElem :: a -> HList c -> HList c
      getHListElem :: HList c -> a

    #if MIN_VERSION_base(4,8,0)
    instance {-# OVERLAPPING #-} ContainsType a (a ': xs) where
    #else
    instance ContainsType a (a ': xs) where
    #endif
      setHListElem :: a -> HList (a : xs) -> HList (a : xs)
    setHListElem a :: a
    a xs :: HList (a : xs)
    xs = a
    a a -> HList xs -> HList (a : xs)
    forall x (xs :: [*]). x -> HList xs -> HList (x : xs)
    :+: case HList (a : xs)
    xs of (_ :+: xr :: HList xs
    xr) -> HList xs
    HList xs
    xr
      getHListElem :: HList (a : xs) -> a
    getHListElem (x :: x
    x :+: _) = a
    x
    x

    instance (ContainsType a xs) => ContainsType a (x ': xs) where
      setHListElem :: a -> HList (x : xs) -> HList (x : xs)
    setHListElem a :: a
    a (x :: x
    x :+: xr :: HList xs
    xr) = x
    x x -> HList xs -> HList (x : xs)
    forall x (xs :: [*]). x -> HList xs -> HList (x : xs)
    :+: a -> HList xs -> HList xs
    forall a (c :: [*]). ContainsType a c => a -> HList c -> HList c
    setHListElem a
    a HList xs
    xr
      getHListElem :: HList (x : xs) -> a
    getHListElem (_ :+: xr :: HList xs
    xr) = HList xs -> a
    forall a (c :: [*]). ContainsType a c => HList c -> a
    getHListElem HList xs
    xr