base: Fix erroneous reference to Data.Reflection in documentation
[ghc.git] / libraries / base / Data / Typeable.hs
1 {-# LANGUAGE Trustworthy #-}
2 {-# LANGUAGE GADTs #-}
3 {-# LANGUAGE NoImplicitPrelude #-}
4 {-# LANGUAGE PolyKinds #-}
5 {-# LANGUAGE ScopedTypeVariables #-}
6 {-# LANGUAGE ConstraintKinds #-}
7 {-# LANGUAGE PatternSynonyms #-}
8 {-# LANGUAGE TypeOperators #-}
9
10 -----------------------------------------------------------------------------
11 -- |
12 -- Module : Data.Typeable
13 -- Copyright : (c) The University of Glasgow, CWI 2001--2004
14 -- License : BSD-style (see the file libraries/base/LICENSE)
15 --
16 -- Maintainer : libraries@haskell.org
17 -- Stability : experimental
18 -- Portability : portable
19 --
20 -- The 'Typeable' class reifies types to some extent by associating type
21 -- representations to types. These type representations can be compared,
22 -- and one can in turn define a type-safe cast operation. To this end,
23 -- an unsafe cast is guarded by a test for type (representation)
24 -- equivalence. The module "Data.Dynamic" uses Typeable for an
25 -- implementation of dynamics. The module "Data.Data" uses Typeable
26 -- and type-safe cast (but not dynamics) to support the \"Scrap your
27 -- boilerplate\" style of generic programming.
28 --
29 -- == Compatibility Notes
30 --
31 -- Since GHC 8.2, GHC has supported type-indexed type representations.
32 -- "Data.Typeable" provides type representations which are qualified over this
33 -- index, providing an interface very similar to the "Typeable" notion seen in
34 -- previous releases. For the type-indexed interface, see "Type.Reflection".
35 --
36 -- Since GHC 7.8, 'Typeable' is poly-kinded. The changes required for this might
37 -- break some old programs involving 'Typeable'. More details on this, including
38 -- how to fix your code, can be found on the
39 -- <https://ghc.haskell.org/trac/ghc/wiki/GhcKinds/PolyTypeable PolyTypeable wiki page>
40 --
41 -----------------------------------------------------------------------------
42
43 module Data.Typeable
44 ( -- * The Typeable class
45 Typeable
46 , typeOf
47 , typeRep
48
49 -- * Propositional equality
50 , (:~:)(Refl)
51 , (:~~:)(HRefl)
52
53 -- * Type-safe cast
54 , cast
55 , eqT
56 , gcast -- a generalisation of cast
57
58 -- * Generalized casts for higher-order kinds
59 , gcast1 -- :: ... => c (t a) -> Maybe (c (t' a))
60 , gcast2 -- :: ... => c (t a b) -> Maybe (c (t' a b))
61
62 -- * A canonical proxy type
63 , Proxy (..)
64
65 -- * Type representations
66 , TypeRep
67 , rnfTypeRep
68 , showsTypeRep
69 , mkFunTy
70
71 -- * Observing type representations
72 , funResultTy
73 , splitTyConApp
74 , typeRepArgs
75 , typeRepTyCon
76 , typeRepFingerprint
77
78 -- * Type constructors
79 , I.TyCon -- abstract, instance of: Eq, Show, Typeable
80 -- For now don't export Module to avoid name clashes
81 , I.tyConPackage
82 , I.tyConModule
83 , I.tyConName
84 , I.rnfTyCon
85 , I.tyConFingerprint
86
87 -- * For backwards compatibility
88 , typeOf1, typeOf2, typeOf3, typeOf4, typeOf5, typeOf6, typeOf7
89 , Typeable1, Typeable2, Typeable3, Typeable4
90 , Typeable5, Typeable6, Typeable7
91 ) where
92
93 import qualified Data.Typeable.Internal as I
94 import Data.Typeable.Internal (Typeable)
95 import Data.Type.Equality
96
97 import Data.Maybe
98 import Data.Proxy
99 import GHC.Fingerprint.Type
100 import GHC.Show
101 import GHC.Base
102
103 -- | A quantified type representation.
104 type TypeRep = I.SomeTypeRep
105
106 -- | Observe a type representation for the type of a value.
107 typeOf :: forall a. Typeable a => a -> TypeRep
108 typeOf _ = I.someTypeRep (Proxy :: Proxy a)
109
110 -- | Takes a value of type @a@ and returns a concrete representation
111 -- of that type.
112 --
113 -- @since 4.7.0.0
114 typeRep :: forall proxy a. Typeable a => proxy a -> TypeRep
115 typeRep = I.someTypeRep
116
117 -- | Show a type representation
118 showsTypeRep :: TypeRep -> ShowS
119 showsTypeRep = shows
120
121 -- | The type-safe cast operation
122 cast :: forall a b. (Typeable a, Typeable b) => a -> Maybe b
123 cast x
124 | Just HRefl <- ta `I.eqTypeRep` tb = Just x
125 | otherwise = Nothing
126 where
127 ta = I.typeRep :: I.TypeRep a
128 tb = I.typeRep :: I.TypeRep b
129
130 -- | Extract a witness of equality of two types
131 --
132 -- @since 4.7.0.0
133 eqT :: forall a b. (Typeable a, Typeable b) => Maybe (a :~: b)
134 eqT
135 | Just HRefl <- ta `I.eqTypeRep` tb = Just Refl
136 | otherwise = Nothing
137 where
138 ta = I.typeRep :: I.TypeRep a
139 tb = I.typeRep :: I.TypeRep b
140
141 -- | A flexible variation parameterised in a type constructor
142 gcast :: forall a b c. (Typeable a, Typeable b) => c a -> Maybe (c b)
143 gcast x = fmap (\Refl -> x) (eqT :: Maybe (a :~: b))
144
145 -- | Cast over @k1 -> k2@
146 gcast1 :: forall c t t' a. (Typeable t, Typeable t')
147 => c (t a) -> Maybe (c (t' a))
148 gcast1 x = fmap (\Refl -> x) (eqT :: Maybe (t :~: t'))
149
150 -- | Cast over @k1 -> k2 -> k3@
151 gcast2 :: forall c t t' a b. (Typeable t, Typeable t')
152 => c (t a b) -> Maybe (c (t' a b))
153 gcast2 x = fmap (\Refl -> x) (eqT :: Maybe (t :~: t'))
154
155 -- | Applies a type to a function type. Returns: @Just u@ if the first argument
156 -- represents a function of type @t -> u@ and the second argument represents a
157 -- function of type @t@. Otherwise, returns @Nothing@.
158 funResultTy :: TypeRep -> TypeRep -> Maybe TypeRep
159 funResultTy (I.SomeTypeRep f) (I.SomeTypeRep x)
160 | Just HRefl <- (I.typeRep :: I.TypeRep Type) `I.eqTypeRep` I.typeRepKind f
161 , I.Fun arg res <- f
162 , Just HRefl <- arg `I.eqTypeRep` x
163 = Just (I.SomeTypeRep res)
164 | otherwise = Nothing
165
166 -- | Build a function type.
167 mkFunTy :: TypeRep -> TypeRep -> TypeRep
168 mkFunTy (I.SomeTypeRep arg) (I.SomeTypeRep res)
169 | Just HRefl <- I.typeRepKind arg `I.eqTypeRep` liftedTy
170 , Just HRefl <- I.typeRepKind res `I.eqTypeRep` liftedTy
171 = I.SomeTypeRep (I.Fun arg res)
172 | otherwise
173 = error $ "mkFunTy: Attempted to construct function type from non-lifted "++
174 "type: arg="++show arg++", res="++show res
175 where liftedTy = I.typeRep :: I.TypeRep Type
176
177 -- | Splits a type constructor application. Note that if the type constructor is
178 -- polymorphic, this will not return the kinds that were used.
179 splitTyConApp :: TypeRep -> (TyCon, [TypeRep])
180 splitTyConApp (I.SomeTypeRep x) = I.splitApps x
181
182 -- | Observe the argument types of a type representation
183 typeRepArgs :: TypeRep -> [TypeRep]
184 typeRepArgs ty = case splitTyConApp ty of (_, args) -> args
185
186 -- | Observe the type constructor of a quantified type representation.
187 typeRepTyCon :: TypeRep -> TyCon
188 typeRepTyCon = I.someTypeRepTyCon
189
190 -- | Takes a value of type @a@ and returns a concrete representation
191 -- of that type.
192 --
193 -- @since 4.7.0.0
194 typeRepFingerprint :: TypeRep -> Fingerprint
195 typeRepFingerprint = I.someTypeRepFingerprint
196
197 -- | Force a 'TypeRep' to normal form.
198 rnfTypeRep :: TypeRep -> ()
199 rnfTypeRep = I.rnfSomeTypeRep
200
201
202 -- Keeping backwards-compatibility
203 typeOf1 :: forall t (a :: *). Typeable t => t a -> TypeRep
204 typeOf1 _ = I.someTypeRep (Proxy :: Proxy t)
205
206 typeOf2 :: forall t (a :: *) (b :: *). Typeable t => t a b -> TypeRep
207 typeOf2 _ = I.someTypeRep (Proxy :: Proxy t)
208
209 typeOf3 :: forall t (a :: *) (b :: *) (c :: *). Typeable t
210 => t a b c -> TypeRep
211 typeOf3 _ = I.someTypeRep (Proxy :: Proxy t)
212
213 typeOf4 :: forall t (a :: *) (b :: *) (c :: *) (d :: *). Typeable t
214 => t a b c d -> TypeRep
215 typeOf4 _ = I.someTypeRep (Proxy :: Proxy t)
216
217 typeOf5 :: forall t (a :: *) (b :: *) (c :: *) (d :: *) (e :: *). Typeable t
218 => t a b c d e -> TypeRep
219 typeOf5 _ = I.someTypeRep (Proxy :: Proxy t)
220
221 typeOf6 :: forall t (a :: *) (b :: *) (c :: *) (d :: *) (e :: *) (f :: *).
222 Typeable t => t a b c d e f -> TypeRep
223 typeOf6 _ = I.someTypeRep (Proxy :: Proxy t)
224
225 typeOf7 :: forall t (a :: *) (b :: *) (c :: *) (d :: *) (e :: *) (f :: *)
226 (g :: *). Typeable t => t a b c d e f g -> TypeRep
227 typeOf7 _ = I.someTypeRep (Proxy :: Proxy t)
228
229 type Typeable1 (a :: * -> *) = Typeable a
230 type Typeable2 (a :: * -> * -> *) = Typeable a
231 type Typeable3 (a :: * -> * -> * -> *) = Typeable a
232 type Typeable4 (a :: * -> * -> * -> * -> *) = Typeable a
233 type Typeable5 (a :: * -> * -> * -> * -> * -> *) = Typeable a
234 type Typeable6 (a :: * -> * -> * -> * -> * -> * -> *) = Typeable a
235 type Typeable7 (a :: * -> * -> * -> * -> * -> * -> * -> *) = Typeable a
236
237 {-# DEPRECATED Typeable1 "renamed to 'Typeable'" #-} -- deprecated in 7.8
238 {-# DEPRECATED Typeable2 "renamed to 'Typeable'" #-} -- deprecated in 7.8
239 {-# DEPRECATED Typeable3 "renamed to 'Typeable'" #-} -- deprecated in 7.8
240 {-# DEPRECATED Typeable4 "renamed to 'Typeable'" #-} -- deprecated in 7.8
241 {-# DEPRECATED Typeable5 "renamed to 'Typeable'" #-} -- deprecated in 7.8
242 {-# DEPRECATED Typeable6 "renamed to 'Typeable'" #-} -- deprecated in 7.8
243 {-# DEPRECATED Typeable7 "renamed to 'Typeable'" #-} -- deprecated in 7.8