Typo
[packages/base.git] / Data / Typeable.hs
1 {-# LANGUAGE Trustworthy #-}
2 {-# LANGUAGE NoImplicitPrelude
3 , OverlappingInstances
4 , ScopedTypeVariables
5 , FlexibleInstances
6 , TypeOperators
7 , PolyKinds
8 , GADTs
9 , MagicHash
10 #-}
11 {-# OPTIONS_GHC -funbox-strict-fields #-}
12
13 -- The -XOverlappingInstances flag allows the user to over-ride
14 -- the instances for Typeable given here. In particular, we provide an instance
15 -- instance ... => Typeable (s a)
16 -- But a user might want to say
17 -- instance ... => Typeable (MyType a b)
18
19 -----------------------------------------------------------------------------
20 -- |
21 -- Module : Data.Typeable
22 -- Copyright : (c) The University of Glasgow, CWI 2001--2004
23 -- License : BSD-style (see the file libraries/base/LICENSE)
24 --
25 -- Maintainer : libraries@haskell.org
26 -- Stability : experimental
27 -- Portability : portable
28 --
29 -- The 'Typeable' class reifies types to some extent by associating type
30 -- representations to types. These type representations can be compared,
31 -- and one can in turn define a type-safe cast operation. To this end,
32 -- an unsafe cast is guarded by a test for type (representation)
33 -- equivalence. The module "Data.Dynamic" uses Typeable for an
34 -- implementation of dynamics. The module "Data.Data" uses Typeable
35 -- and type-safe cast (but not dynamics) to support the \"Scrap your
36 -- boilerplate\" style of generic programming.
37 --
38 -- == Compatibility Notes
39 --
40 -- Since GHC 7.8, 'Typeable' is poly-kinded. The changes required for this might
41 -- break some old programs involving 'Typeable'. More details on this, including
42 -- how to fix your code, can be found on the
43 -- <https://ghc.haskell.org/trac/ghc/wiki/GhcKinds/PolyTypeable PolyTypeable wiki page>
44 --
45 -----------------------------------------------------------------------------
46
47 module Data.Typeable
48 (
49 -- * The Typeable class
50 Typeable,
51 typeRep,
52
53 -- * Propositional equality
54 (:~:)(Refl),
55
56 -- * For backwards compatibility
57 typeOf, typeOf1, typeOf2, typeOf3, typeOf4, typeOf5, typeOf6, typeOf7,
58 Typeable1, Typeable2, Typeable3, Typeable4, Typeable5, Typeable6,
59 Typeable7,
60
61 -- * Type-safe cast
62 cast,
63 eqT,
64 gcast, -- a generalisation of cast
65
66 -- * Generalized casts for higher-order kinds
67 gcast1, -- :: ... => c (t a) -> Maybe (c (t' a))
68 gcast2, -- :: ... => c (t a b) -> Maybe (c (t' a b))
69
70 -- * A canonical proxy type
71 Proxy (..),
72
73 -- * Type representations
74 TypeRep, -- abstract, instance of: Eq, Show, Typeable
75 showsTypeRep,
76
77 TyCon, -- abstract, instance of: Eq, Show, Typeable
78 tyConString,
79 tyConPackage,
80 tyConModule,
81 tyConName,
82
83 -- * Construction of type representations
84 -- mkTyCon, -- :: String -> TyCon
85 mkTyCon3, -- :: String -> String -> String -> TyCon
86 mkTyConApp, -- :: TyCon -> [TypeRep] -> TypeRep
87 mkAppTy, -- :: TypeRep -> TypeRep -> TypeRep
88 mkFunTy, -- :: TypeRep -> TypeRep -> TypeRep
89
90 -- * Observation of type representations
91 splitTyConApp, -- :: TypeRep -> (TyCon, [TypeRep])
92 funResultTy, -- :: TypeRep -> TypeRep -> Maybe TypeRep
93 typeRepTyCon, -- :: TypeRep -> TyCon
94 typeRepArgs, -- :: TypeRep -> [TypeRep]
95 ) where
96
97 import Data.Typeable.Internal hiding (mkTyCon)
98 import Data.Type.Equality
99
100 import Unsafe.Coerce
101 import Data.Maybe
102 import GHC.Base
103
104 -------------------------------------------------------------
105 --
106 -- Type-safe cast
107 --
108 -------------------------------------------------------------
109
110 -- | The type-safe cast operation
111 cast :: forall a b. (Typeable a, Typeable b) => a -> Maybe b
112 cast x = if typeRep (Proxy :: Proxy a) == typeRep (Proxy :: Proxy b)
113 then Just $ unsafeCoerce x
114 else Nothing
115
116 -- | Extract a witness of equality of two types
117 --
118 -- /Since: 4.7.0.0/
119 eqT :: forall a b. (Typeable a, Typeable b) => Maybe (a :~: b)
120 eqT = if typeRep (Proxy :: Proxy a) == typeRep (Proxy :: Proxy b)
121 then Just $ unsafeCoerce Refl
122 else Nothing
123
124 -- | A flexible variation parameterised in a type constructor
125 gcast :: forall a b c. (Typeable a, Typeable b) => c a -> Maybe (c b)
126 gcast x = fmap (\Refl -> x) (eqT :: Maybe (a :~: b))
127
128 -- | Cast over @k1 -> k2@
129 gcast1 :: forall c t t' a. (Typeable t, Typeable t')
130 => c (t a) -> Maybe (c (t' a))
131 gcast1 x = fmap (\Refl -> x) (eqT :: Maybe (t :~: t'))
132
133 -- | Cast over @k1 -> k2 -> k3@
134 gcast2 :: forall c t t' a b. (Typeable t, Typeable t')
135 => c (t a b) -> Maybe (c (t' a b))
136 gcast2 x = fmap (\Refl -> x) (eqT :: Maybe (t :~: t'))
137