278a76fafa4949d69ca3a0d865d49393272ae855
[ghc-base.git] / Data / Generics / List.hs
1 -----------------------------------------------------------------------------
2 -- |
3 -- Module      :  Data.Generics.List
4 -- Copyright   :  (c) The University of Glasgow, CWI 2001--2004
5 -- License     :  BSD-style (see the file libraries/base/LICENSE)
6 -- 
7 -- Maintainer  :  libraries@haskell.org
8 -- Stability   :  experimental
9 -- Portability :  non-portable
10 --
11 -- \"Scrap your boilerplate\" --- Generic programming in Haskell 
12 -- See <http://www.cs.vu.nl/boilerplate/>. The present module illustrates
13 -- one possible treatment of polymorphic datatypes for specialising
14 -- generic functions.
15 --
16 -----------------------------------------------------------------------------
17
18 module Data.Generics.List ( 
19
20         -- * Processing polymorphic lists
21         isList,
22         isNil,
23         isCons,
24         lgmapQ
25
26
27  ) where
28
29
30 ------------------------------------------------------------------------------
31
32 #ifdef __HADDOCK__
33 import Prelude
34 #endif
35 import Data.Maybe
36 import Data.Generics.Basics
37
38 -------------------------------------------------------------
39 --
40 --      Processing polymorphic lists
41 --
42 -------------------------------------------------------------
43
44
45 -- | Test for list datatype
46 isList :: Data a => a -> Bool
47 isList x = typerepTyCon (typeOf x) ==
48            typerepTyCon (typeOf (undefined::[()]))
49
50
51 -- | Test for nil
52 isNil :: Data a => a -> Bool
53 isNil x = toConstr x == toConstr ([]::[()])
54
55
56 -- | Test for cons
57 isCons :: Data a => a -> Bool
58 isCons x = toConstr x == toConstr (():[])
59
60
61 -- | gmapQ for polymorphic lists; Nothing for other than lists
62 lgmapQ :: forall a q. Data a => (forall a. Data a => a -> q) -> a -> Maybe [q]
63 lgmapQ f x =
64   if not $ isList x 
65    then Nothing
66    else Just ( if isNil x
67                  then []
68                  else if isCons x
69                    then ( gmapQi 0 f x : gmapQi 1 (fromJust . lgmapQ f) x )
70                    else error "lgmapQ"
71              )