-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Like Data.Dynamic/Data.Typeable but with support for rank-1 polymorphic types
--   
--   <a>Data.Typeable</a> and <a>Data.Dynamic</a> only support monomorphic
--   types. In this package we provide similar functionality but with
--   support for rank-1 polymorphic types.
@package rank1dynamic
@version 0.4.0


-- | Runtime type representation of terms with support for rank-1
--   polymorphic types with type variables of kind *.
--   
--   The essence of this module is that we use the standard <a>Typeable</a>
--   representation of <a>Data.Typeable</a> but we introduce a special
--   (empty) data type <a>TypVar</a> which represents type variables.
--   <a>TypVar</a> is indexed by an arbitrary other data type, giving you
--   an unbounded number of type variables; for convenience, we define
--   <a>ANY</a>, <a>ANY1</a>, .., <a>ANY9</a>.
--   
--   <ul>
--   <li><i>Examples of isInstanceOf</i></li>
--   </ul>
--   
--   <pre>
--   -- We CANNOT use a term of type 'Int -&gt; Bool' as 'Int -&gt; Int'
--   &gt; typeOf (undefined :: Int -&gt; Int) `isInstanceOf` typeOf (undefined :: Int -&gt; Bool)
--   Left "Cannot unify Int and Bool"
--   
--   -- We CAN use a term of type 'forall a. a -&gt; Int' as 'Int -&gt; Int'
--   &gt; typeOf (undefined :: Int -&gt; Int) `isInstanceOf` typeOf (undefined :: ANY -&gt; Int)
--   Right ()
--   
--   -- We CAN use a term of type 'forall a b. a -&gt; b' as 'forall a. a -&gt; a'
--   &gt; typeOf (undefined :: ANY -&gt; ANY) `isInstanceOf` typeOf (undefined :: ANY -&gt; ANY1)
--   Right ()
--   
--   -- We CANNOT use a term of type 'forall a. a -&gt; a' as 'forall a b. a -&gt; b'
--   &gt; typeOf (undefined :: ANY -&gt; ANY1) `isInstanceOf` typeOf (undefined :: ANY -&gt; ANY)
--   Left "Cannot unify Succ and Zero"
--   
--   -- We CAN use a term of type 'forall a. a' as 'forall a. a -&gt; a'
--   &gt; typeOf (undefined :: ANY -&gt; ANY) `isInstanceOf` typeOf (undefined :: ANY)
--   Right ()
--   
--   -- We CANNOT use a term of type 'forall a. a -&gt; a' as 'forall a. a'
--   &gt; typeOf (undefined :: ANY) `isInstanceOf` typeOf (undefined :: ANY -&gt; ANY)
--   Left "Cannot unify Skolem and -&gt;"
--   </pre>
--   
--   (Admittedly, the quality of the type errors could be improved.)
--   
--   <ul>
--   <li><i>Examples of funResultTy</i></li>
--   </ul>
--   
--   <pre>
--   -- Apply fn of type (forall a. a -&gt; a) to arg of type Bool gives Bool
--   &gt; funResultTy (typeOf (undefined :: ANY -&gt; ANY)) (typeOf (undefined :: Bool))
--   Right Bool
--   
--   -- Apply fn of type (forall a b. a -&gt; b -&gt; a) to arg of type Bool gives forall a. a -&gt; Bool
--   &gt; funResultTy (typeOf (undefined :: ANY -&gt; ANY1 -&gt; ANY)) (typeOf (undefined :: Bool))
--   Right (ANY -&gt; Bool) -- forall a. a -&gt; Bool
--   
--   -- Apply fn of type (forall a. (Bool -&gt; a) -&gt; a) to argument of type (forall a. a -&gt; a) gives Bool
--   &gt; funResultTy (typeOf (undefined :: (Bool -&gt; ANY) -&gt; ANY)) (typeOf (undefined :: ANY -&gt; ANY))
--   Right Bool
--   
--   -- Apply fn of type (forall a b. a -&gt; b -&gt; a) to arg of type (forall a. a -&gt; a) gives (forall a b. a -&gt; b -&gt; b)
--   &gt; funResultTy (typeOf (undefined :: ANY -&gt; ANY1 -&gt; ANY)) (typeOf (undefined :: ANY1 -&gt; ANY1))
--   Right (ANY -&gt; ANY1 -&gt; ANY1)
--   
--   -- Cannot apply function of type (forall a. (a -&gt; a) -&gt; a -&gt; a) to arg of type (Int -&gt; Bool)
--   &gt; funResultTy (typeOf (undefined :: (ANY -&gt; ANY) -&gt; (ANY -&gt; ANY))) (typeOf (undefined :: Int -&gt; Bool))
--   Left "Cannot unify Int and Bool"
--   </pre>
module Data.Rank1Typeable

-- | Dynamic type representation with support for rank-1 types
data TypeRep

-- | The type representation of any <a>Typeable</a> term
typeOf :: Typeable a => a -> TypeRep

-- | Split a type representation into the application of a type constructor
--   and its argument
splitTyConApp :: TypeRep -> (TyCon, [TypeRep])

-- | Inverse of <a>splitTyConApp</a>
mkTyConApp :: TyCon -> [TypeRep] -> TypeRep

-- | <tt>t1 <a>isInstanceOf</a> t2</tt> checks if <tt>t1</tt> is an
--   instance of <tt>t2</tt>
isInstanceOf :: TypeRep -> TypeRep -> Either TypeError ()

-- | <tt>funResultTy t1 t2</tt> is the type of the result when applying a
--   function of type <tt>t1</tt> to an argument of type <tt>t2</tt>
funResultTy :: TypeRep -> TypeRep -> Either TypeError TypeRep

-- | If <a>isInstanceOf</a> fails it returns a type error
type TypeError = String
data TypVar a
data Zero
data Succ a
type V0 = Zero
type V1 = Succ V0
type V2 = Succ V1
type V3 = Succ V2
type V4 = Succ V3
type V5 = Succ V4
type V6 = Succ V5
type V7 = Succ V6
type V8 = Succ V7
type V9 = Succ V8
type ANY = TypVar V0
type ANY1 = TypVar V1
type ANY2 = TypVar V2
type ANY3 = TypVar V3
type ANY4 = TypVar V4
type ANY5 = TypVar V5
type ANY6 = TypVar V6
type ANY7 = TypVar V7
type ANY8 = TypVar V8
type ANY9 = TypVar V9

-- | The class <a>Typeable</a> allows a concrete representation of a type
--   to be calculated.
class Typeable k (a :: k)
instance GHC.Classes.Eq Data.Rank1Typeable.TypeRep
instance Data.Binary.Class.Binary Data.Rank1Typeable.TypeRep
instance GHC.Show.Show Data.Rank1Typeable.TypeRep
instance GHC.Classes.Eq Data.Rank1Typeable.TyCon
instance GHC.Show.Show Data.Rank1Typeable.TyCon


-- | Dynamic values with support for rank-1 polymorphic types.
--   
--   <ul>
--   <li><i>Examples of fromDynamic</i></li>
--   </ul>
--   
--   These examples correspond to the <a>isInstanceOf</a> examples in
--   <a>Data.Rank1Typeable</a>.
--   
--   <pre>
--   &gt; do f &lt;- fromDynamic (toDynamic (even :: Int -&gt; Bool)) ; return $ (f :: Int -&gt; Int) 0
--   Left "Cannot unify Int and Bool"
--   
--   &gt; do f &lt;- fromDynamic (toDynamic (const 1 :: ANY -&gt; Int)) ; return $ (f :: Int -&gt; Int) 0
--   Right 1
--   
--   &gt; do f &lt;- fromDynamic (toDynamic (unsafeCoerce :: ANY1 -&gt; ANY2)) ; return $ (f :: Int -&gt; Int) 0
--   Right 0
--   
--   &gt; do f &lt;- fromDynamic (toDynamic (id :: ANY -&gt; ANY)) ; return $ (f :: Int -&gt; Bool) 0
--   Left "Cannot unify Bool and Int"
--   
--   &gt; do f &lt;- fromDynamic (toDynamic (undefined :: ANY)) ; return $ (f :: Int -&gt; Int) 0
--   Right *** Exception: Prelude.undefined
--   
--   &gt; do f &lt;- fromDynamic (toDynamic (id :: ANY -&gt; ANY)) ; return $ (f :: Int)
--   Left "Cannot unify Int and -&gt;"
--   </pre>
--   
--   <ul>
--   <li><i>Examples of dynApply</i></li>
--   </ul>
--   
--   These examples correspond to the <a>funResultTy</a> examples in
--   <a>Data.Rank1Typeable</a>.
--   
--   <pre>
--   &gt; do app &lt;- toDynamic (id :: ANY -&gt; ANY) `dynApply` toDynamic True ; f &lt;- fromDynamic app ; return $ (f :: Bool)
--   Right True
--   
--   &gt; do app &lt;- toDynamic (const :: ANY -&gt; ANY1 -&gt; ANY) `dynApply` toDynamic True ; f &lt;- fromDynamic app ; return $ (f :: Int -&gt; Bool) 0
--   Right True
--   
--   &gt; do app &lt;- toDynamic (($ True) :: (Bool -&gt; ANY) -&gt; ANY) `dynApply` toDynamic (id :: ANY -&gt; ANY) ; f &lt;- fromDynamic app ; return (f :: Bool)
--   Right True
--   
--   &gt; app &lt;- toDynamic (const :: ANY -&gt; ANY1 -&gt; ANY) `dynApply` toDynamic (id :: ANY -&gt; ANY) ; f &lt;- fromDynamic app ; return $ (f :: Int -&gt; Bool -&gt; Bool) 0 True
--   Right True
--   
--   &gt; do app &lt;- toDynamic ((\f -&gt; f . f) :: (ANY -&gt; ANY) -&gt; ANY -&gt; ANY) `dynApply` toDynamic (even :: Int -&gt; Bool) ; f &lt;- fromDynamic app ; return (f :: ())
--   Left "Cannot unify Int and Bool"
--   </pre>
--   
--   <ul>
--   <li><i>Using toDynamic</i></li>
--   </ul>
--   
--   When using polymorphic values you need to give an explicit type
--   annotation:
--   
--   <pre>
--   &gt; toDynamic id
--   
--   &lt;interactive&gt;:46:1:
--       Ambiguous type variable `a0' in the constraint:
--         (Typeable a0) arising from a use of `toDynamic'
--       Probable fix: add a type signature that fixes these type variable(s)
--       In the expression: toDynamic id
--       In an equation for `it': it = toDynamic id
--   </pre>
--   
--   versus
--   
--   <pre>
--   &gt; toDynamic (id :: ANY -&gt; ANY)
--   &lt;&lt;ANY -&gt; ANY&gt;&gt;
--   </pre>
--   
--   Note that these type annotation are checked by ghc like any other:
--   
--   <pre>
--   &gt; toDynamic (id :: ANY -&gt; ANY1)
--   
--   &lt;interactive&gt;:45:12:
--       Couldn't match expected type `V1' with actual type `V0'
--       Expected type: ANY -&gt; ANY1
--         Actual type: ANY -&gt; ANY
--       In the first argument of `toDynamic', namely `(id :: ANY -&gt; ANY1)'
--       In the expression: toDynamic (id :: ANY -&gt; ANY1)
--   </pre>
module Data.Rank1Dynamic

-- | Encapsulate an object and its type
data Dynamic

-- | Introduce a dynamic value
toDynamic :: Typeable a => a -> Dynamic

-- | Eliminate a dynamic value
fromDynamic :: Typeable a => Dynamic -> Either TypeError a

-- | If <a>isInstanceOf</a> fails it returns a type error
type TypeError = String

-- | The type representation of a dynamic value
dynTypeRep :: Dynamic -> TypeRep

-- | Apply one dynamic value to another
dynApply :: Dynamic -> Dynamic -> Either TypeError Dynamic

-- | Construct a dynamic value with a user-supplied type rep
--   
--   This function is unsafe because we have no way of verifying that the
--   provided type representation matches the value.
--   
--   Since 0.3.2.0.
unsafeToDynamic :: TypeRep -> a -> Dynamic
instance GHC.Show.Show Data.Rank1Dynamic.Dynamic
