# LANGUAGE MultiParamTypeClasses , FunctionalDependencies , 
              OverlappingInstances , UndecidableInstances #
             OverlappingInstances, UndecidableInstances #-}

--
  Test case adopted from the HList library
-- /~ralf/HList/
--

module FakePrelude where


--
  Type - level Booleans ; nothing weird
--
data HTrue; hTrue :: HTrue; hTrue = undefined
data HFalse; hFalse :: HFalse; hFalse = undefined
class HBool x; instance HBool HTrue; instance HBool HFalse
instance Show HTrue where show _ = "HTrue"
instance Show HFalse where show _ = "HFalse"


--
-- Type-level type equality
--
class HBool b => TypeEq x y b | x y -> b


--
-- Value-level incarnation; nothing too weird.
  Rely on lazy show for type - level Booleans
--
typeEq :: TypeEq t t' b => t -> t' -> b
typeEq = undefined


--
-- Type-level cast
--
class TypeCast x y | x -> y, y -> x
 where
  typeCast :: x -> y


 /~ralf/HList/




 Type-level type equality


 Value-level incarnation; nothing too weird.


 Type-level cast

# LANGUAGE MultiParamTypeClasses , FunctionalDependencies , 
              OverlappingInstances , UndecidableInstances #
             OverlappingInstances, UndecidableInstances #-}

  Test case adopted from the HList library

module FakePrelude where


  Type - level Booleans ; nothing weird
data HTrue; hTrue :: HTrue; hTrue = undefined
data HFalse; hFalse :: HFalse; hFalse = undefined
class HBool x; instance HBool HTrue; instance HBool HFalse
instance Show HTrue where show _ = "HTrue"
instance Show HFalse where show _ = "HFalse"


class HBool b => TypeEq x y b | x y -> b


  Rely on lazy show for type - level Booleans
typeEq :: TypeEq t t' b => t -> t' -> b
typeEq = undefined


class TypeCast x y | x -> y, y -> x
 where
  typeCast :: x -> y
