cdbb0d49562e68edc7f4e2c18a685174c88fd26b
[ghc.git] / libraries / base / Data / Proxy.hs
1 {-# LANGUAGE Trustworthy #-}
2 {-# LANGUAGE NoImplicitPrelude #-}
3 {-# LANGUAGE PolyKinds #-}
4
5 -----------------------------------------------------------------------------
6 -- |
7 -- Module : Data.Proxy
8 -- License : BSD-style (see the LICENSE file in the distribution)
9 --
10 -- Maintainer : libraries@haskell.org
11 -- Stability : experimental
12 -- Portability : portable
13 --
14 -- Definition of a Proxy type (poly-kinded in GHC)
15 --
16 -- @since 4.7.0.0
17 -----------------------------------------------------------------------------
18
19 module Data.Proxy
20 (
21 Proxy(..), asProxyTypeOf
22 , KProxy(..)
23 ) where
24
25 import GHC.Base
26 import GHC.Show
27 import GHC.Read
28 import GHC.Enum
29 import GHC.Arr
30
31 -- $setup
32 -- >>> import Data.Void
33 -- >>> import Prelude
34
35 -- | 'Proxy' is a type that holds no data, but has a phantom parameter of
36 -- arbitrary type (or even kind). Its use is to provide type information, even
37 -- though there is no value available of that type (or it may be too costly to
38 -- create one).
39 --
40 -- Historically, @'Proxy' :: 'Proxy' a@ is a safer alternative to the
41 -- @'undefined :: a'@ idiom.
42 --
43 -- >>> Proxy :: Proxy (Void, Int -> Int)
44 -- Proxy
45 --
46 -- Proxy can even hold types of higher kinds,
47 --
48 -- >>> Proxy :: Proxy Either
49 -- Proxy
50 --
51 -- >>> Proxy :: Proxy Functor
52 -- Proxy
53 --
54 -- >>> Proxy :: Proxy complicatedStructure
55 -- Proxy
56 data Proxy t = Proxy deriving ( Bounded -- ^ @since 4.7.0.0
57 , Read -- ^ @since 4.7.0.0
58 )
59
60 -- | A concrete, promotable proxy type, for use at the kind level
61 -- There are no instances for this because it is intended at the kind level only
62 data KProxy (t :: *) = KProxy
63
64 -- It's common to use (undefined :: Proxy t) and (Proxy :: Proxy t)
65 -- interchangeably, so all of these instances are hand-written to be
66 -- lazy in Proxy arguments.
67
68 -- | @since 4.7.0.0
69 instance Eq (Proxy s) where
70 _ == _ = True
71
72 -- | @since 4.7.0.0
73 instance Ord (Proxy s) where
74 compare _ _ = EQ
75
76 -- | @since 4.7.0.0
77 instance Show (Proxy s) where
78 showsPrec _ _ = showString "Proxy"
79
80 -- | @since 4.7.0.0
81 instance Enum (Proxy s) where
82 succ _ = errorWithoutStackTrace "Proxy.succ"
83 pred _ = errorWithoutStackTrace "Proxy.pred"
84 fromEnum _ = 0
85 toEnum 0 = Proxy
86 toEnum _ = errorWithoutStackTrace "Proxy.toEnum: 0 expected"
87 enumFrom _ = [Proxy]
88 enumFromThen _ _ = [Proxy]
89 enumFromThenTo _ _ _ = [Proxy]
90 enumFromTo _ _ = [Proxy]
91
92 -- | @since 4.7.0.0
93 instance Ix (Proxy s) where
94 range _ = [Proxy]
95 index _ _ = 0
96 inRange _ _ = True
97 rangeSize _ = 1
98 unsafeIndex _ _ = 0
99 unsafeRangeSize _ = 1
100
101 -- | @since 4.9.0.0
102 instance Semigroup (Proxy s) where
103 _ <> _ = Proxy
104 sconcat _ = Proxy
105 stimes _ _ = Proxy
106
107 -- | @since 4.7.0.0
108 instance Monoid (Proxy s) where
109 mempty = Proxy
110 mconcat _ = Proxy
111
112 -- | @since 4.7.0.0
113 instance Functor Proxy where
114 fmap _ _ = Proxy
115 {-# INLINE fmap #-}
116
117 -- | @since 4.7.0.0
118 instance Applicative Proxy where
119 pure _ = Proxy
120 {-# INLINE pure #-}
121 _ <*> _ = Proxy
122 {-# INLINE (<*>) #-}
123
124 -- | @since 4.9.0.0
125 instance Alternative Proxy where
126 empty = Proxy
127 {-# INLINE empty #-}
128 _ <|> _ = Proxy
129 {-# INLINE (<|>) #-}
130
131 -- | @since 4.7.0.0
132 instance Monad Proxy where
133 _ >>= _ = Proxy
134 {-# INLINE (>>=) #-}
135
136 -- | @since 4.9.0.0
137 instance MonadPlus Proxy
138
139 -- | 'asProxyTypeOf' is a type-restricted version of 'const'.
140 -- It is usually used as an infix operator, and its typing forces its first
141 -- argument (which is usually overloaded) to have the same type as the tag
142 -- of the second.
143 --
144 -- >>> import Data.Word
145 -- >>> :type asProxyTypeOf 123 (Proxy :: Proxy Word8)
146 -- asProxyTypeOf 123 (Proxy :: Proxy Word8) :: Word8
147 --
148 -- Note the lower-case @proxy@ in the definition. This allows any type
149 -- constructor with just one argument to be passed to the function, for example
150 -- we could also write
151 --
152 -- >>> import Data.Word
153 -- >>> :type asProxyTypeOf 123 (Just (undefined :: Word8))
154 -- asProxyTypeOf 123 (Just (undefined :: Word8)) :: Word8
155 asProxyTypeOf :: a -> proxy a -> a
156 asProxyTypeOf = const
157 {-# INLINE asProxyTypeOf #-}
158