1 -----------------------------------------------------------------------------
3 -- Module : Data.Generics
4 -- Copyright : (c) The University of Glasgow 2001
5 -- License : BSD-style (see the file libraries/base/LICENSE)
7 -- Maintainer : libraries@haskell.org
8 -- Stability : experimental
9 -- Portability : non-portable
11 -- Data types for generic definitions (GHC only).
13 -----------------------------------------------------------------------------
15 module Data.Generics (
18 -- * Data types for the sum-of-products type encoding
19 (:*:)(..), (:+:)(..), Unit(..),
22 -- * Typeable and types-save cast
23 Typeable(..), cast, sameType,
25 -- * The Data class and related types
26 Data( gmapT, gmapQ, gmapM,
27 gfoldl, gfoldr, gunfold,
31 -- * Transformations (T), queries (Q), monadic transformations (Q),
32 -- and twin transformations (TT)
33 GenericT, GenericQ, GenericM,
38 -- * Traversal combinators
39 everything, something, everywhere, everywhereBut,
40 synthesize, branches, undefineds,
42 -- * Generic operations: equality, zip, read, show
43 geq, gzip, gshow, gread,
46 match, tick, count, alike
51 import Prelude -- So that 'make depend' works
53 #ifdef __GLASGOW_HASKELL__
54 import GHC.Base ( (:*:)(..), (:+:)(..), Unit(..) )
62 ---------------------------------------------
64 -- Operations involving Typeable only
66 ---------------------------------------------
68 -- | Apply a function if appropriate or preserve term
69 mkT :: (Typeable a, Typeable b) => (b -> b) -> a -> a
70 mkT f = case cast f of
74 -- | Apply a function if appropriate or return a constant
75 mkQ :: (Typeable a, Typeable b) => r -> (b -> r) -> a -> r
76 (r `mkQ` br) a = case cast a of
82 -- | Apply a monadic transformation if appropriate; resort to return otherwise
83 mkM :: (Typeable a, Typeable b, Typeable (m a), Typeable (m b), Monad m)
84 => (b -> m b) -> a -> m a
85 mkM f = case cast f of
89 -- | Extend a transformation
90 extT :: (Typeable a, Typeable b) => (a -> a) -> (b -> b) -> a -> a
91 extT f g = case cast g of
96 extQ :: (Typeable a, Typeable b) => (a -> q) -> (b -> q) -> a -> q
97 extQ f g a = case cast a of
101 -- | Extend a monadic transformation
102 extM :: (Typeable a, Typeable b, Typeable (m a), Typeable (m b), Monad m)
103 => (a -> m a) -> (b -> m b) -> a -> m a
104 extM f g = case cast g of
108 -- | Test two entities to be of the same type
109 sameType :: (Typeable a, Typeable b) => a -> b -> Bool
110 sameType (_::a) = False `mkQ` (\(_::a) -> True)
114 -- | Make a twin transformation
115 -- Note: Should be worked on
116 mkTT :: (Typeable a, Typeable b, Typeable c)
119 mkTT (f::a ->a->a) x y =
120 case (cast x,cast y) of
121 (Just (x'::a),Just (y'::a)) -> cast (f x' y')
127 -------------------------------------------------------------------
129 -- The representation of datatype constructors
130 -- To be extended by fixity, associativity, and what else?
132 -------------------------------------------------------------------
134 -- | Describes a constructor
135 data Constr = Constr { conString :: String }
139 ---------------------------------------------
141 -- The Data class and its operations
143 ---------------------------------------------
145 -- A class for traversal
147 class Typeable a => Data a where
148 gmapT :: (forall b. Data b => b -> b) -> a -> a
149 gmapQ :: (forall a. Data a => a -> u) -> a -> [u]
150 gmapM :: Monad m => (forall a. Data a => a -> m a) -> a -> m a
152 gfoldl :: (forall a b. Data a => c (a -> b) -> a -> c b)
153 -> (forall g. g -> c g)
156 gfoldr :: (forall a b. Data a => a -> c (a -> b) -> c b)
157 -> (forall g. g -> c g)
161 -- | Find the constructor
164 -- | Does not look at a; Could live in Typeable as well maybe
165 consOf :: a -> [Constr]
167 gunfold :: (forall a b. Data a => c (a -> b) -> c b)
168 -> (forall g. g -> c g)
172 -- No default method for gfoldl, gunfold, conOf, consOf
174 -- Default methods for gfoldr, gmapT, gmapQ, gmapM,
175 -- in terms of gfoldl
177 gfoldr f z = gfoldl (flip f) z
179 gmapT f x = unID (gfoldl k ID x)
181 k (ID c) x = ID (c (f x))
183 gmapQ f x = unQ (gfoldl k (const (Q id)) x) []
185 k (Q c) x = Q (\rs -> c (f x : rs))
187 gmapM f = gfoldl k return
194 -- Default definition for gfoldl copes with basic datatypes
199 A variation for gmapQ using an ordinary constant type constructor.
200 A problem is here that the associativety might be wrong.
202 newtype Phantom x y = Phantom x
203 runPhantom (Phantom x) = x
205 gmapQ f = runPhantom . gfoldl f' z
207 f' r a = Phantom (f a : runPhantom r)
208 z = const (Phantom [])
212 -- | Instructive type synonyms
213 type GenericT = forall a. Data a => a -> a
214 type GenericQ r = forall a. Data a => a -> r
215 type GenericM m = forall a. Data a => a -> m a
218 -- Auxiliary type constructors for the default methods (not exported)
219 newtype ID x = ID { unID :: x }
220 newtype Q r a = Q { unQ :: [r]->[r] }
221 newtype TQ r a = TQ { unTQ :: ([r]->[r],[GenericQ' r]) }
223 -- A twin variation on gmapQ
224 -- Note: Nested GenericQ (GenericQ ...) buggy in GHC 5.04
227 (forall a b. (Data a, Data b) => a -> b -> r)
228 -> (forall a b. (Data a, Data b) => a -> b -> [r])
230 tmapQ g x y = fst (unTQ (gfoldl k z y)) []
232 k (TQ (c,l)) x = TQ (\rs -> c (unQ' (head l) x:rs), tail l)
233 z _ = TQ (id,gmapQ (\x -> Q' (g x)) x)
235 -- A first-class polymorphic version of GenericQ
237 data GenericQ' u = Q' { unQ' :: forall a. Data a => a -> u }
241 -- A first-class polymorphic version of GenericM
243 data Monad m => GenericM' m = M' { unM' :: forall a. Data a => a -> m a }
245 -- A type constructor for monadic twin transformations
246 newtype TM m a = TM { unTM :: (m a,[GenericM' m]) }
248 -- A twin variation on gmapM
250 tmapM :: forall m. Monad m
251 => (forall a b. (Data a, Data b) => a -> b -> m b)
252 -> (forall a b. (Data a, Data b) => a -> b -> m b)
253 tmapM g x y = fst (unTM (gfoldl k z y))
255 k (TM (f,l)) x = TM (f >>= \f' -> unM' (head l) x >>= return . f',tail l)
256 z f = TM (return f,gmapQ (\x -> M' (g x)) x)
258 ---------------------------------------------
260 -- Combinators for data structure traversal
262 ---------------------------------------------
264 -- | Summarise all nodes in top-down, left-to-right
267 -> (forall a. Data a => a -> r)
270 = foldl k (f x) (gmapQ (everything k f) x)
274 -- | Look up something by means of a recognizer
275 something :: (forall a. Data a => a -> Maybe u)
276 -> (forall a. Data a => a -> Maybe u)
277 something = everything orElse
281 -- | Left-biased choice
282 orElse :: Maybe a -> Maybe a -> Maybe a
283 x `orElse` y = case x of
289 -- | Some people like folding over the first maybe instead
290 x `orElse'` y = maybe y Just x
294 -- | Bottom-up synthesis of a data structure
295 synthesize :: (forall a. Data a => a -> s -> s)
298 -> (forall a. Data a => a -> s)
299 synthesize f o z x = f x (foldr o z (gmapQ (synthesize f o z) x))
303 -- | Apply a transformation everywhere in bottom-up manner
304 everywhere :: (forall a. Data a => a -> a)
305 -> (forall a. Data a => a -> a)
306 everywhere f = f . gmapT (everywhere f)
310 -- | Variation with stop condition
311 everywhereBut :: GenericQ Bool
312 -> GenericT -> GenericT
315 | otherwise = f (gmapT (everywhereBut q f) x)
319 -- | Monadic variation
320 everywhereM :: (Monad m, Data a)
321 => (forall b. Data b => b -> m b)
323 everywhereM f x = do x' <- gmapM (everywhereM f) x
327 -- | Count immediate subterms
328 branches :: Data a => a -> Int
329 branches = length . gmapQ (const ())
332 -- | Construct term with undefined subterms
333 undefineds :: Data a => Constr -> Maybe a
334 undefineds i = gunfold (maybe Nothing (\x -> Just (x undefined)))
339 ---------------------------------------------
341 -- Generic equality, zip, read, show
343 ---------------------------------------------
345 -- | Generic equality
346 geq :: forall a. Data a => a -> a -> Bool
349 geq' :: forall a b. (Data a, Data b) => a -> b -> Bool
350 geq' x y = and ( (conString (conOf x) == conString (conOf y))
357 gzip :: (forall a b. (Data a, Data b) => a -> b -> Maybe b)
358 -> (forall a b. (Data a, Data b) => a -> b -> Maybe b)
362 if conString (conOf x) == conString (conOf y)
363 then tmapM (gzip f) x y
368 gshow :: Data a => a -> String
370 ++ conString (conOf t)
371 ++ concat (gmapQ ((++) " ". gshow) t)
376 -- The type constructor for unfold a la ReadS from the Prelude
377 newtype GRead i a = GRead (i -> Maybe (a, i))
378 unGRead (GRead x) = x
383 gread :: Data a => String -> Maybe (a, String)
385 = do s' <- return $ dropWhile ((==) ' ') s
386 guard (not (s' == ""))
387 guard (head s' == '(')
388 (c,s'') <- breakConOf (dropWhile ((==) ' ') (tail s'))
389 (a,s''') <- unGRead (gunfold f z c) s''
390 guard (not (s''' == ""))
391 guard (head s''' == ')')
394 f cab = GRead (\s -> do (ab,s') <- unGRead cab s
397 z c = GRead (\s -> Just (c,s))
400 -- Get Constr at front
401 breakConOf :: String -> Maybe (Constr, String)
403 -- Assume an infix operators in parantheses
405 = case break ((==) ')') s of
406 (s'@(_:_),(')':s'')) -> Just (Constr ("(" ++ s' ++ ")"), s'')
409 -- Special treatment of multiple token constructors
410 breakConOf ('[':']':s) = Just (Constr "[]",s)
412 -- Try lex for ordinary constructor and basic datatypes
415 [(s'@(_:_),s'')] -> Just (Constr s',s'')
420 ---------------------------------------------
422 -- Instances of the Data class
424 ---------------------------------------------
426 instance Data Float where
427 conOf x = Constr (show x)
429 gunfold f z c = z (read (conString c))
431 instance Data Char where
432 conOf x = Constr (show x)
434 gunfold f z c = z (read (conString c))
437 instance Data String where
438 conOf x = Constr (show x)
440 gunfold f z = z . read
444 instance Data Bool where
445 conOf False = Constr "False"
446 conOf True = Constr "True"
447 consOf _ = [Constr "False",Constr "True"]
448 gunfold f z (Constr "False") = z False
449 gunfold f z (Constr "True") = z True
451 instance Data a => Data [a] where
453 gmapT f (x:xs) = (f x:f xs)
455 gmapQ f (x:xs) = [f x,f xs]
456 gmapM f [] = return []
457 gmapM f (x:xs) = f x >>= \x' -> f xs >>= \xs' -> return (x':xs')
459 gfoldl f z (x:xs) = z (:) `f` x `f` xs
461 gfoldr f z (x:xs) = f xs (f x (z (:)))
462 conOf [] = Constr "[]"
463 conOf (_:_) = Constr "(:)"
464 gunfold f z (Constr "[]") = z []
465 gunfold f z (Constr "(:)") = f (f (z (:)))
466 consOf _ = [Constr "[]",Constr "(:)"]
471 {- ----------------------------------------------------
472 Comments illustrating generic instances
474 An illustrative instance for a nested datatype
476 data Nest a = Box a | Wrap (Nest [a])
478 nestTc = mkTyCon "Nest"
480 instance Typeable a => Typeable (Nest a) where
481 typeOf n = mkAppTy nestTc [typeOf (paratype n)]
483 paratype :: Nest a -> a
484 paratype _ = undefined
486 instance (Data a, Data [a]) => Data (Nest a) where
487 gmapT f (Box a) = Box (f a)
488 gmapT f (Wrap w) = Wrap (f w)
489 gmapQ f (Box a) = [f a]
490 gmapQ f (Wrap w) = [f w]
491 gmapM f (Box a) = f a >>= return . Box
492 gmapM f (Wrap w) = f w >>= return . Wrap
493 conOf (Box _) = Constr "Box"
494 conOf (Wrap _) = Constr "Wrap"
495 consOf _ = map Constr ["Box","Wrap"]
496 gunfold f z "Box" = f (z Box)
497 gunfold f z "Wrap" = f (z Wrap)
501 -- An illustrative instance for local quantors
503 instance Data GenericT' where
504 gmapT f (T' g) = (T' (f g))
505 conOf _ = Constr "T'"
506 consOf _ = map Constr ["T'"]
510 instance Typeable GenericT' where
515 -- The instance for function types
516 -- needs -fallow-undecidable-instances
518 instance Typeable (a -> b) => Data (a -> b) where
522 conOf _ = Constr "->"
523 consOf _ = [Constr "->"]
527 --------------------------------------------------------
528 -- A first-class polymorphic version of GenericT
529 -- Note: needed because [GenericT] not valid in GHC 5.04
531 {- Comment out for now (SLPJ 17 Apr 03)
533 data GenericT' = T' (forall a. Data a => a -> a)
536 -- A type constructor for twin transformations
538 newtype IDL r a = IDL (a,[GenericT'])
543 -- A twin variation on gmapT
545 tmapT :: (forall a b. (Data a, Data b) => a -> b -> b)
546 -> (forall a b. (Data a, Data b) => a -> b -> b)
547 tmapT g x y = fst (unIDL (gfoldl k z y))
549 k (IDL (f,l)) x = IDL (f (unT' (head l) x),tail l)
550 z f = IDL (f,gmapQ (\x -> T' (g x)) x)
554 -- A first-class polymorphic version of GenericQ
556 data GenericQ' u = Q' (forall a. Data a => a -> u)
568 -- Compute arity of term constructor
571 -- | Turn a predicate into a filter
572 match :: (Typeable a, Typeable b) => (a -> Bool) -> b -> Maybe a
573 match f = Nothing `mkQ` (\ a -> if f a then Just a else Nothing)
577 -- | Turn a predicate into a ticker
578 tick :: (Typeable a, Typeable b) => (a -> Bool) -> b -> Int
579 tick f = 0 `mkQ` (\a -> if f a then 1 else 0)
583 -- | Turn a ticker into a counter
584 count :: (Typeable a, Data b) => (a -> Bool) -> b -> Int
585 count f = everything (+) (tick f)
589 -- | Lift a monomorphic predicate to the polymorphic level
590 alike :: (Typeable a, Typeable b) => (a -> Bool) -> b -> Bool
591 alike f = False `mkQ` f