3 {-# OPTIONS_GHC -XNoImplicitPrelude -XTypeOperators #-}
5 module GHC.Generics where
11 data (:+:) a b = Inl a | Inr b
12 data (:*:) a b = a :*: b
17 {-# OPTIONS_GHC -XNoImplicitPrelude #-}
18 {-# OPTIONS_GHC -XEmptyDataDecls #-}
19 {-# OPTIONS_GHC -XMultiParamTypeClasses #-}
20 {-# OPTIONS_GHC -XTypeSynonymInstances #-}
21 {-# OPTIONS_GHC -XTypeOperators #-}
22 {-# OPTIONS_GHC -XKindSignatures #-}
23 {-# OPTIONS_GHC -XFunctionalDependencies #-}
26 -- * Generic representation types
27 V1, U1(..), Par1(..), Rec1(..), K1(..), M1(..)
28 , (:+:)(..), (:*:)(..), (:.:)(..)
30 -- ** Synonyms for convenience
35 , Datatype(..), Constructor(..), Selector(..), NoSelector
36 , Fixity(..), Associativity(..), Arity(..), prec
38 -- * Representable type classes
39 , Representable0(..), Representable1(..)
42 -- * Representations for base types
43 , Rep0Char, Rep0Int, Rep0Float
44 , Rep0Maybe, Rep1Maybe
49 import {-# SOURCE #-} GHC.Types -- ([](..), Int, Char, Bool(..))
51 --------------------------------------------------------------------------------
52 -- Representation types
53 --------------------------------------------------------------------------------
55 -- | Void: used for datatypes without constructors
58 -- | Unit: used for constructors without arguments
61 -- | Used for marking occurrences of the parameter
62 newtype Par1 p = Par1 { unPar1 :: p }
65 -- | Recursive calls of kind * -> *
66 newtype Rec1 f p = Rec1 { unRec1 :: f p }
68 -- | Constants, additional parameters and recursion of kind *
69 newtype K1 i c p = K1 { unK1 :: c }
71 -- | Meta-information (constructor names, etc.)
72 newtype M1 i c f p = M1 { unM1 :: f p }
74 -- | Sums: encode choice between constructors
76 data (:+:) f g p = L1 (f p) | R1 (g p)
78 -- | Products: encode multiple arguments to constructors
80 data (:*:) f g p = f p :*: g p
82 -- | Composition of functors
84 newtype (:.:) f g p = Comp1 { unComp1 :: f (g p) }
86 -- | Tag for K1: recursion (of kind *)
88 -- | Tag for K1: parameters (other than the last)
91 -- | Type synonym for encoding recursion (of kind *)
93 -- | Type synonym for encoding parameters (other than the last)
96 -- | Tag for M1: datatype
98 -- | Tag for M1: constructor
100 -- | Tag for M1: record selector
103 -- | Type synonym for encoding meta-information for datatypes
106 -- | Type synonym for encoding meta-information for constructors
109 -- | Type synonym for encoding meta-information for record selectors
113 -- | Class for datatypes that represent datatypes
114 class Datatype d where
115 -- | The name of the datatype (unqualified)
116 datatypeName :: t d (f :: * -> *) a -> [Char]
117 -- | The fully-qualified name of the module where the type is declared
118 moduleName :: t d (f :: * -> *) a -> [Char]
121 -- | Class for datatypes that represent records
122 class Selector s where
123 -- | The name of the selector
124 selName :: t s (f :: * -> *) a -> [Char]
126 -- | Used for constructor fields without a name
129 instance Selector NoSelector where selName _ = ""
131 -- | Class for datatypes that represent data constructors
132 class Constructor c where
133 -- | The name of the constructor
134 conName :: t c (f :: * -> *) a -> [Char]
136 -- | The fixity of the constructor
137 conFixity :: t c (f :: * -> *) a -> Fixity
140 -- | Marks if this constructor is a record
141 conIsRecord :: t c (f :: * -> *) a -> Bool
142 conIsRecord _ = False
144 -- | Marks if this constructor is a tuple,
145 -- returning arity >=0 if so, <0 if not
146 conIsTuple :: t c (f :: * -> *) a -> Arity
147 conIsTuple _ = NoArity
150 -- | Datatype to represent the arity of a tuple.
151 data Arity = NoArity | Arity Int
152 -- deriving (Eq, Show, Ord, Read)
153 -- TODO: Add these instances to the Prelude
155 -- | Datatype to represent the fixity of a constructor. An infix
156 -- | declaration directly corresponds to an application of 'Infix'.
157 data Fixity = Prefix | Infix Associativity Int
158 -- deriving (Eq, Show, Ord, Read)
159 -- TODO: Add these instances to the Prelude
161 -- | Get the precedence of a fixity value.
162 prec :: Fixity -> Int
166 -- | Datatype to represent the associativy of a constructor
167 data Associativity = LeftAssociative
170 -- deriving (Eq, Show, Ord, Read)
171 -- TODO: Add these instances to the Prelude
174 -- | Representable types of kind *
175 class Representable0 a rep | a -> rep where
176 -- | Convert from the datatype to its representation
178 -- | Convert from the representation to the datatype
181 -- | Representable types of kind * -> *
182 class Representable1 f rep | f -> rep where
183 -- | Convert from the datatype to its representation
184 from1 :: f a -> rep a
185 -- | Convert from the representation to the datatype
188 --------------------------------------------------------------------------------
189 -- Representation for base types
190 --------------------------------------------------------------------------------
192 -- Representation types
195 instance Representable1 Par1 Rep1Par1 where
199 type Rep1Rec1 f = Rec1 f
200 instance Representable1 (Rec1 f) (Rep1Rec1 f) where
207 type Rep0Char = Rec0 Char
208 instance Representable0 Char Rep0Char where
212 type Rep0Int = Rec0 Int
213 instance Representable0 Int Rep0Int where
217 type Rep0Float = Rec0 Float
218 instance Representable0 Float Rep0Float where
230 instance Datatype Maybe_ where
231 datatypeName _ = "Maybe"
232 moduleName _ = "Representation"
234 instance Constructor Nothing_ where
235 conName _ = "Nothing"
237 instance Constructor Just_ where
240 type Rep0Maybe a = D1 Maybe_ (C1 Nothing_ U1 :+: C1 Just_ (Par0 a))
241 instance Representable0 (Maybe a) (Rep0Maybe a) where
242 from0 Nothing = M1 (L1 (M1 U1))
243 from0 (Just x) = M1 (R1 (M1 (K1 x)))
244 to0 (M1 (L1 (M1 U1))) = Nothing
245 to0 (M1 (R1 (M1 (K1 x)))) = Just x
247 type Rep1Maybe = D1 Maybe_ (C1 Nothing_ U1 :+: C1 Just_ Par1)
248 instance Representable1 Maybe Rep1Maybe where
249 from1 Nothing = M1 (L1 (M1 U1))
250 from1 (Just x) = M1 (R1 (M1 (Par1 x)))
251 to1 (M1 (L1 (M1 U1))) = Nothing
252 to1 (M1 (R1 (M1 (Par1 x)))) = Just x
259 instance Datatype [a] where
260 datatypeName _ = "[]"
261 moduleName _ = "Data.List"
263 instance Constructor Nil__ where conName _ = "[]"
264 instance Constructor Cons__ where
266 conFixity _ = Infix RightAssociative 5
268 type Rep0List a = D1 List__ ((C1 Nil__ U1) :+: (C1 Cons__ (Par0 a :*: Rec0 [a])))
269 instance Representable0 [a] (Rep0List a) where
270 from0 [] = M1 (L1 (M1 U1))
271 from0 (h:t) = M1 (R1 (M1 (K1 h :*: K1 t)))
272 to0 (M1 (L1 (M1 U1))) = []
273 to0 (M1 (R1 (M1 (K1 h :*: K1 t)))) = h : t
275 type Rep1List = D1 List__ ((C1 Nil__ U1) :+: (C1 Cons__ (Par1 :*: Rec1 [])))
276 instance Representable1 [] Rep1List where
277 from1 [] = M1 (L1 (M1 U1))
278 from1 (h:t) = M1 (R1 (M1 (Par1 h :*: Rec1 t)))
279 to1 (M1 (L1 (M1 U1))) = []
280 to1 (M1 (R1 (M1 (Par1 h :*: Rec1 t)))) = h : t