1 -----------------------------------------------------------------------------
3 -- Module : Data.Generics.Basics
4 -- Copyright : (c) The University of Glasgow, CWI 2001--2003
5 -- License : BSD-style (see the file libraries/base/LICENSE)
7 -- Maintainer : libraries@haskell.org
8 -- Stability : experimental
9 -- Portability : non-portable
11 -- \"Scrap your boilerplate\" --- Generic programming in Haskell
12 -- See <http://www.cs.vu.nl/boilerplate/>. The present module provides
13 -- the Data class with its primitives for generic programming.
15 -----------------------------------------------------------------------------
17 module Data.Generics.Basics (
19 -- Module Data.Typeable re-exported for convenience
22 -- * The Data class for processing constructor applications
24 gfoldl, -- :: ... -> a -> c a
25 toConstr, -- :: a -> Constr
26 fromConstr, -- :: Constr -> a
27 dataTypeOf -- :: a -> DataType
31 -- * Constructor representations
32 Constr, -- abstract, instance of: Eq, Show
33 ConIndex, -- alias for Int, start at 1
34 Fixity(..), -- instance of: Eq, Show
35 DataType, -- abstract, instance of: Show
37 -- * Constructing constructor representations
38 mkConstr, -- :: ConIndex -> String -> Fixity -> Constr
39 mkDataType, -- :: [Constr] -> DataType
41 -- * Observing constructor representations
42 conString, -- :: Constr -> String
43 conFixity, -- :: Constr -> Fixity
44 conIndex, -- :: Constr -> ConIndex
45 stringCon, -- :: DataType -> String -> Maybe Constr
46 indexCon, -- :: DataType -> ConIndex -> Constr
47 maxConIndex, -- :: DataType -> ConIndex
48 dataTypeCons, -- :: DataType -> [Constr]
50 -- * Generic maps defined in terms of gfoldl
59 -- * Generic unfolding defined in terms of gfoldl and fromConstr
60 gunfoldM -- :: Monad m => ... -> m a
65 ------------------------------------------------------------------------------
73 ------------------------------------------------------------------------------
77 ------------------------------------------------------------------------------
81 The Data class comprehends a fundamental primitive "gfoldl" for
82 folding over constructor applications, say terms. This primitive can
83 be instantiated in several ways to map over the immediate subterms of
84 a term; see the "gmap" combinators later in this module. Indeed, a
85 generic programmer does not necessarily need to use the ingenious
86 gfoldl primitive but rather the intuitive "gmap" combinators. The
87 "gfoldl" primitive is completed by means to query top-level
88 constructors, to turn constructor representations into proper terms,
89 and to list all possible datatype constructors. This completion
90 allows us to serve generic programming scenarios like read, show,
91 equality, term generation.
95 class Typeable a => Data a where
99 Folding constructor applications ("gfoldl")
101 The combinator takes two arguments "f" and "z" to fold over a term
102 "x". The result type is defined in terms of "x" but variability is
103 achieved by means of type constructor "c" for the construction of the
104 actual result type. The purpose of the argument "z" is to define how
105 the empty constructor application is folded. So "z" is like the
106 neutral / start element for list folding. The purpose of the argument
107 "f" is to define how the nonempty constructor application is
108 folded. That is, "f" takes the folded "tail" of the constructor
109 application and its head, i.e., an immediate subterm, and combines
110 them in some way. See the Data instances in this file for an
111 illustration of "gfoldl". Conclusion: the type of gfoldl is a
112 headache, but operationally it is simple generalisation of a list
117 -- | Left-associative fold operation for constructor applications
118 gfoldl :: (forall a b. Data a => c (a -> b) -> a -> c b)
119 -> (forall g. g -> c g)
122 -- Default definition for gfoldl
123 -- which copes immediately with basic datatypes
128 -- | Obtaining the constructor from a given datum.
129 -- For proper terms, this is meant to be the top-level constructor.
130 -- Primitive datatypes are here viewed as potentially infinite sets of
131 -- values (i.e., constructors).
133 toConstr :: a -> Constr
136 -- | Building a term from a constructor
137 fromConstr :: Constr -> a
140 -- | Provide access to list of all constructors
141 dataTypeOf :: a -> DataType
144 ------------------------------------------------------------------------------
146 -- Typical generic maps defined in terms of gfoldl
148 ------------------------------------------------------------------------------
152 The combinators gmapT, gmapQ, gmapM, ... can all be defined in terms
153 of gfoldl. We provide corresponding default definitions leaving open
154 the opportunity to provide datatype-specific definitions.
156 (The inclusion of the gmap combinators as members of class Data allows
157 the programmer or the compiler to derive specialised, and maybe more
158 efficient code per datatype. Note: gfoldl is more higher-order than
159 the gmap combinators. This is subject to ongoing benchmarking
160 experiments. It might turn out that the gmap combinators will be moved
161 out of the class Data.)
163 Conceptually, the definition of the gmap combinators in terms of the
164 primitive gfoldl requires the identification of the gfoldl function
165 arguments. Technically, we also need to identify the type constructor
166 "c" for the construction of the result type from the folded term type.
171 -- | A generic transformation that maps over the immediate subterms
172 gmapT :: (forall b. Data b => b -> b) -> a -> a
174 -- Use an identity datatype constructor ID (see below)
175 -- to instantiate the type constructor c in the type of gfoldl,
176 -- and perform injections ID and projections unID accordingly.
178 gmapT f x = unID (gfoldl k ID x)
180 k (ID c) x = ID (c (f x))
183 -- | A generic query with a left-associative binary operator
184 gmapQl :: (r -> r' -> r) -> r -> (forall a. Data a => a -> r') -> a -> r
185 gmapQl o r f = unCONST . gfoldl k z
187 k c x = CONST $ (unCONST c) `o` f x
192 In the definition of gmapQ? combinators, we use phantom type
193 constructors for the "c" in the type of "gfoldl" because the result
194 type of a query does not involve the (polymorphic) type of the term
195 argument. In the definition of gmapQl we simply use the plain constant
196 type constructor because gfoldl is left-associative anyway and so it
197 is readily suited to fold a left-associative binary operation over the
198 immediate subterms. In the definition of gmapQr, extra effort is
199 needed. We use a higher-order accumulation trick to mediate between
200 left-associative constructor application vs. right-associative binary
201 operation (e.g., (:)). When the query is meant to compute a value of
202 type r, then the result type withing generic folding is r -> r. So the
203 result of folding is a function to which we finally pass the right
208 -- | A generic query with a right-associative binary operator
209 gmapQr :: (r' -> r -> r) -> r -> (forall a. Data a => a -> r') -> a -> r
210 gmapQr o r f x = unQr (gfoldl k (const (Qr id)) x) r
212 k (Qr c) x = Qr (\r -> c (f x `o` r))
214 -- | A generic query that processes the immediate subterms and returns a list
215 gmapQ :: (forall a. Data a => a -> u) -> a -> [u]
216 gmapQ f = gmapQr (:) [] f
219 -- | A generic monadic transformation that maps over the immediate subterms
220 gmapM :: Monad m => (forall a. Data a => a -> m a) -> a -> m a
222 -- Use immediately the monad datatype constructor
223 -- to instantiate the type constructor c in the type of gfoldl,
224 -- so injection and projection is done by return and >>=.
226 gmapM f = gfoldl k return
233 -- | Transformation of at least one immediate subterm does not fail
234 gmapMp :: MonadPlus m => (forall a. Data a => a -> m a) -> a -> m a
238 The type constructor that we use here simply keeps track of the fact
239 if we already succeeded for an immediate subterm; see Mp below. To
240 this end, we couple the monadic computation with a Boolean.
244 gmapMp f x = unMp (gfoldl k z x) >>= \(x',b) ->
245 if b then return x' else mzero
247 z g = Mp (return (g,False))
249 = Mp ( c >>= \(h,b) ->
250 (f x >>= \x' -> return (h x',True))
251 `mplus` return (h x,b)
254 -- | Transformation of one immediate subterm with success
255 gmapMo :: MonadPlus m => (forall a. Data a => a -> m a) -> a -> m a
259 We use the same pairing trick as for gmapMp,
260 i.e., we use an extra Bool component to keep track of the
261 fact whether an immediate subterm was processed successfully.
262 However, we cut of mapping over subterms once a first subterm
263 was transformed successfully.
267 gmapMo f x = unMp (gfoldl k z x) >>= \(x',b) ->
268 if b then return x' else mzero
270 z g = Mp (return (g,False))
272 = Mp ( c >>= \(h,b) -> if b
274 else (f x >>= \x' -> return (h x',True))
275 `mplus` return (h x,b)
279 -- | The identity type constructor needed for the definition of gmapT
280 newtype ID x = ID { unID :: x }
283 -- | The constant type constructor needed for the definition of gmapQl
284 newtype CONST c a = CONST { unCONST :: c }
287 -- | The type constructor used in definition of gmapQr
288 newtype Qr r a = Qr { unQr :: r -> r }
291 -- | The type constructor used in definition of gmapMp
292 newtype Mp m x = Mp { unMp :: m (x, Bool) }
296 ------------------------------------------------------------------------------
298 -- Constructor representations
300 ------------------------------------------------------------------------------
303 -- | Representation of constructors
305 -- The prime case for proper datatype constructors
306 DataConstr ConIndex String Fixity
308 -- Provision for built-in types
310 | IntegerConstr Integer
314 -- Provision for any type that can be read/shown as string
315 | StringConstr String
317 -- Provision for function types
320 deriving (Show, Typeable)
323 -- Equality of datatype constructors via index.
324 -- Use designated equalities for primitive types.
326 instance Eq Constr where
327 (DataConstr i1 _ _) == (DataConstr i2 _ _) = i1 == i2
328 (IntConstr i1) == (IntConstr i2) = i1 == i2
329 (IntegerConstr i1) == (IntegerConstr i2) = i1 == i2
330 (FloatConstr i1) == (FloatConstr i2) = i1 == i2
331 (CharConstr i1) == (CharConstr i2) = i1 == i2
332 (StringConstr i1) == (StringConstr i2) = i1 == i2
336 -- | Unique index for datatype constructors.
337 -- Textual order is respected. Starts at 1.
342 -- | Fixity of constructors
344 | Infix -- Later: add associativity and precedence
347 -- | A package of constructor representations;
348 -- could be a list, an array, a balanced tree, or others.
351 -- The prime case for algebraic datatypes
354 -- Provision for built-in types
360 -- Provision for any type that can be read/shown as string
363 -- Provision for function types
369 ------------------------------------------------------------------------------
371 -- Constructing constructor representations
373 ------------------------------------------------------------------------------
376 -- | Make a representation for a datatype constructor
377 mkConstr :: ConIndex -> String -> Fixity -> Constr
378 -- ToDo: consider adding arity?
379 mkConstr = DataConstr
381 -- | Make a package of constructor representations
382 mkDataType :: [Constr] -> DataType
383 mkDataType = DataType
386 ------------------------------------------------------------------------------
388 -- Observing constructor representations
390 ------------------------------------------------------------------------------
393 -- | Turn a constructor into a string
394 conString :: Constr -> String
395 conString (DataConstr _ str _) = str
396 conString (IntConstr int) = show int
397 conString (IntegerConstr int) = show int
398 conString (FloatConstr real) = show real
399 conString (CharConstr char) = show char
400 conString (StringConstr str) = show str
401 conString FunConstr = "->"
404 -- | Determine fixity of a constructor;
405 -- undefined for primitive types.
406 conFixity :: Constr -> Fixity
407 conFixity (DataConstr _ _ fix) = fix
408 conFixity _ = undefined
411 -- | Determine index of a constructor.
412 -- Undefined for primitive types.
413 conIndex :: Constr -> ConIndex
414 conIndex (DataConstr idx _ _) = idx
415 conIndex _ = undefined
418 -- | Lookup a constructor via a string
419 stringCon :: DataType -> String -> Maybe Constr
420 stringCon (DataType cs) str = worker cs
425 (DataConstr _ str' _) -> if str == str'
428 _ -> undefined -- other forms of Constr not valid here
430 stringCon IntType str = Just . IntConstr $ read str
431 stringCon IntegerType str = Just . IntegerConstr $ read str
432 stringCon FloatType str = Just . FloatConstr $ read str
433 stringCon CharType str = Just . CharConstr $ read str
434 stringCon StringType str = Just . StringConstr $ read str
435 stringCon FunType str = Just FunConstr
438 -- | Lookup a constructor by its index;
439 --- not defined for primitive types.
440 indexCon :: DataType -> ConIndex -> Constr
441 indexCon (DataType cs) idx = cs !! (idx-1)
442 indexCon _ _ = undefined -- otherwise
445 -- | Return maximum index;
446 -- 0 for primitive types
447 maxConIndex :: DataType -> ConIndex
448 maxConIndex (DataType cs) = length cs
449 maxConIndex _ = 0 -- otherwise
452 -- | Return all constructors in increasing order of indicies;
453 -- empty list for primitive types
454 dataTypeCons :: DataType -> [Constr]
455 dataTypeCons (DataType cs) = cs
456 dataTypeCons _ = [] -- otherwise
459 ------------------------------------------------------------------------------
461 -- Instances of the Data class for Prelude types
463 ------------------------------------------------------------------------------
465 -- Basic datatype Int; folding and unfolding is trivial
466 instance Data Int where
467 toConstr x = IntConstr x
468 fromConstr (IntConstr x) = x
469 dataTypeOf _ = IntType
471 -- Another basic datatype instance
472 instance Data Integer where
473 toConstr x = IntegerConstr x
474 fromConstr (IntegerConstr x) = x
475 dataTypeOf _ = IntegerType
477 -- Another basic datatype instance
478 instance Data Float where
479 toConstr x = FloatConstr x
480 fromConstr (FloatConstr x) = x
481 dataTypeOf _ = FloatType
483 -- Another basic datatype instance
484 instance Data Char where
485 toConstr x = CharConstr x
486 fromConstr (CharConstr x) = x
487 dataTypeOf _ = CharType
489 -- A basic datatype without a specific branch in Constr
490 instance Data Rational where
491 toConstr x = StringConstr (show x)
492 fromConstr (StringConstr x) = read x
493 dataTypeOf _ = StringType
496 -- Bool as the most trivial algebraic datatype;
497 -- define top-level definitions for representations.
500 falseConstr = mkConstr 1 "False" Prefix
501 trueConstr = mkConstr 2 "True" Prefix
502 boolDataType = mkDataType [falseConstr,trueConstr]
504 instance Data Bool where
505 toConstr False = falseConstr
506 toConstr True = trueConstr
507 fromConstr c = case conIndex c of
510 dataTypeOf _ = boolDataType
514 -- Lists as an example of a polymorphic algebraic datatype.
515 -- Cons-lists are terms with two immediate subterms.
518 nilConstr = mkConstr 1 "[]" Prefix
519 consConstr = mkConstr 2 "(:)" Infix
520 listDataType = mkDataType [nilConstr,consConstr]
522 instance Data a => Data [a] where
524 gfoldl f z (x:xs) = z (:) `f` x `f` xs
525 toConstr [] = nilConstr
526 toConstr (_:_) = consConstr
527 fromConstr c = case conIndex c of
529 2 -> undefined:undefined
530 dataTypeOf _ = listDataType
533 -- The gmaps are given as an illustration.
534 -- This shows that the gmaps for lists are different from list maps.
537 gmapT f (x:xs) = (f x:f xs)
539 gmapQ f (x:xs) = [f x,f xs]
540 gmapM f [] = return []
541 gmapM f (x:xs) = f x >>= \x' -> f xs >>= \xs' -> return (x':xs')
545 -- Yet another polymorphic datatype constructor
549 nothingConstr = mkConstr 1 "Nothing" Prefix
550 justConstr = mkConstr 2 "Just" Prefix
551 maybeDataType = mkDataType [nothingConstr,justConstr]
553 instance Data a => Data (Maybe a) where
554 gfoldl f z Nothing = z Nothing
555 gfoldl f z (Just x) = z Just `f` x
556 toConstr Nothing = nothingConstr
557 toConstr (Just _) = justConstr
558 fromConstr c = case conIndex c of
561 dataTypeOf _ = maybeDataType
564 -- Yet another polymorphic datatype constructor.
568 pairConstr = mkConstr 1 "(,)" Infix
569 productDataType = mkDataType [pairConstr]
571 instance (Data a, Data b) => Data (a,b) where
572 gfoldl f z (a,b) = z (,) `f` a `f` b
573 toConstr _ = pairConstr
574 fromConstr c = case conIndex c of
575 1 -> (undefined,undefined)
576 dataTypeOf _ = productDataType
581 We should better not FOLD over characters in a string for efficiency.
582 However, the following instance would clearly overlap with the
583 instance for polymorphic lists. Given the current scheme of allowing
584 overlapping instances, this would imply that ANY module that imports
585 Data.Generics would need to explicitly and generally allow overlapping
586 instances. This is prohibitive and calls for a more constrained model
587 of allowing overlapping instances. The present instance would be
588 sensible even more for UNFOLDING. In the definition of "gread"
589 (generic read --- based on unfolding), we succeed handling strings in a
590 special way by using a type-specific case for String.
592 instance Data String where
593 toConstr x = StringConstr x
594 fromConstr (StringConstr x) = x
595 dataTypeOf _ = StringType
599 -- A last resort for functions
600 instance (Typeable a, Typeable b) => Data (a -> b) where
601 toConstr _ = FunConstr
602 fromConstr _ = undefined
603 dataTypeOf _ = FunType
606 ------------------------------------------------------------------------------
610 ------------------------------------------------------------------------------
612 -- | Construct an initial with undefined immediate subterms
613 -- and then map over the skeleton to fill in proper terms.
615 gunfoldM :: (Monad m, Data a)
617 -> (forall a. Data a => m a)
619 gunfoldM c f = gmapM (const f) $ fromConstr c