--
-- Maintainer : libraries@haskell.org
-- Stability : experimental
--- Portability : non-portable
+-- Portability : non-portable (local universal quantification)
--
--- \"Scrap your boilerplate\" --- Generic programming in Haskell
--- See <http://www.cs.vu.nl/boilerplate/>. The present module provides
--- the Data class with its primitives for generic programming.
+-- \"Scrap your boilerplate\" --- Generic programming in Haskell.
+-- See <http://www.cs.vu.nl/boilerplate/>. This module provides
+-- the 'Data' class with its primitives for generic programming.
--
-----------------------------------------------------------------------------
module Data.Generics.Basics (
- -- Module Data.Typeable re-exported for convenience
+ -- * Module Data.Typeable re-exported for convenience
module Data.Typeable,
-- * The Data class for processing constructor applications
Data(
gfoldl, -- :: ... -> a -> c a
+ gunfold, -- :: ... -> Constr -> c a
toConstr, -- :: a -> Constr
- fromConstr, -- :: Constr -> a
dataTypeOf, -- :: a -> DataType
- cast0to1, -- mediate types and unary type constructors
- cast0to2 -- mediate types and binary type constructors
+ dataCast1, -- mediate types and unary type constructors
+ dataCast2, -- mediate types and binary type constructors
+ -- Generic maps defined in terms of gfoldl
+ gmapT,
+ gmapQ,
+ gmapQl,
+ gmapQr,
+ gmapQi,
+ gmapM,
+ gmapMp,
+ gmapMo
),
-- * Datatype representations
DataType, -- abstract, instance of: Show
- Constr, -- abstract, instance of: Eq, Show
- DataRep(..), -- instance of: Eq, Show
- ConRep(..), -- instance of: Eq, Show
- ConIndex, -- alias for Int, start at 1
- Fixity(..), -- instance of: Eq, Show
-
- -- * Observers for datatype representations
- dataTypeCon, -- :: DataType -> String
- dataTypeRep, -- :: DataType -> DataRep
- conDataType, -- :: Constr -> DataType
- conRep, -- :: Constr -> ConRep
- repCon, -- :: DataType -> ConRep -> Constr
-
- -- * Representations of algebraic data types
- mkDataType, -- :: String -> [Constr] -> DataType
- mkDataCon, -- :: DataType -> String -> Fixity -> Constr
- algTypeCons, -- :: DataType -> [Constr]
- conFixity, -- :: Constr -> Fixity
-
- -- * From strings to constr's and vice versa: all data types
- conString, -- :: Constr -> String
- stringCon, -- :: DataType -> String -> Maybe Constr
-
- -- * Convenience funtions: algebraic data types
- isAlgType, -- :: DataType -> Bool
- indexCon, -- :: DataType -> ConIndex -> Constr
- conIndex, -- :: Constr -> ConIndex
- maxConIndex, -- :: DataType -> ConIndex
-
- -- * Representation of primitive types
+ -- ** Constructors
+ mkDataType, -- :: String -> [Constr] -> DataType
mkIntType, -- :: String -> DataType
mkFloatType, -- :: String -> DataType
mkStringType, -- :: String -> DataType
- mkIntCon, -- :: DataType -> Integer -> Constr
- mkFloatCon, -- :: DataType -> Double -> Constr
- mkStringCon, -- :: DataType -> String -> Constr
-
- -- * Non-representations for non-presentable types
mkNorepType, -- :: String -> DataType
+ -- ** Observers
+ dataTypeName, -- :: DataType -> String
+ DataRep(..), -- instance of: Eq, Show
+ dataTypeRep, -- :: DataType -> DataRep
+ -- ** Convenience functions
+ repConstr, -- :: DataType -> ConstrRep -> Constr
+ isAlgType, -- :: DataType -> Bool
+ dataTypeConstrs,-- :: DataType -> [Constr]
+ indexConstr, -- :: DataType -> ConIndex -> Constr
+ maxConstrIndex, -- :: DataType -> ConIndex
isNorepType, -- :: DataType -> Bool
+ -- * Data constructor representations
+ Constr, -- abstract, instance of: Eq, Show
+ ConIndex, -- alias for Int, start at 1
+ Fixity(..), -- instance of: Eq, Show
+ -- ** Constructors
+ mkConstr, -- :: DataType -> String -> Fixity -> Constr
+ mkIntConstr, -- :: DataType -> Integer -> Constr
+ mkFloatConstr, -- :: DataType -> Double -> Constr
+ mkStringConstr, -- :: DataType -> String -> Constr
+ -- ** Observers
+ constrType, -- :: Constr -> DataType
+ ConstrRep(..), -- instance of: Eq, Show
+ constrRep, -- :: Constr -> ConstrRep
+ constrFields, -- :: Constr -> [String]
+ constrFixity, -- :: Constr -> Fixity
+ -- ** Convenience function: algebraic data types
+ constrIndex, -- :: Constr -> ConIndex
+ -- ** From strings to constructors and vice versa: all data types
+ showConstr, -- :: Constr -> String
+ readConstr, -- :: DataType -> String -> Maybe Constr
+
-- * Convenience functions: take type constructors apart
tyconUQname, -- :: String -> String
tyconModule, -- :: String -> String
- -- * Generic maps defined in terms of gfoldl
- gmapT,
- gmapQ,
- gmapQl,
- gmapQr,
- gmapQi,
- gmapM,
- gmapMp,
- gmapMo,
+ -- * Generic operations defined in terms of 'gunfold'
+ fromConstr, -- :: Constr -> a
+ fromConstrB, -- :: ... -> Constr -> a
+ fromConstrM -- :: Monad m => ... -> Constr -> m a
) where
------------------------------------------------------------------------------
-#ifdef __HADDOCK__
-import Prelude
-#endif
+import Prelude -- necessary to get dependencies right
import Data.Typeable
import Data.Maybe
--
------------------------------------------------------------------------------
-{-
-
-The Data class comprehends a fundamental primitive "gfoldl" for
+{- |
+The 'Data' class comprehends a fundamental primitive 'gfoldl' for
folding over constructor applications, say terms. This primitive can
-be instantiated in several ways to map over the immediate subterms of
-a term; see the "gmap" combinators later in this module. Indeed, a
-generic programmer does not necessarily need to use the ingenious
-gfoldl primitive but rather the intuitive "gmap" combinators. The
-"gfoldl" primitive is completed by means to query top-level
-constructors, to turn constructor representations into proper terms,
-and to list all possible datatype constructors. This completion
-allows us to serve generic programming scenarios like read, show,
-equality, term generation.
+be instantiated in several ways to map over the immediate subterms
+of a term; see the @gmap@ combinators later in this class. Indeed, a
+generic programmer does not necessarily need to use the ingenious gfoldl
+primitive but rather the intuitive @gmap@ combinators. The 'gfoldl'
+primitive is completed by means to query top-level constructors, to
+turn constructor representations into proper terms, and to list all
+possible datatype constructors. This completion allows us to serve
+generic programming scenarios like read, show, equality, term generation.
+
+The combinators 'gmapT', 'gmapQ', 'gmapM', etc are all provided with
+default definitions in terms of 'gfoldl', leaving open the opportunity
+to provide datatype-specific definitions.
+(The inclusion of the @gmap@ combinators as members of class 'Data'
+allows the programmer or the compiler to derive specialised, and maybe
+more efficient code per datatype. /Note/: 'gfoldl' is more higher-order
+than the @gmap@ combinators. This is subject to ongoing benchmarking
+experiments. It might turn out that the @gmap@ combinators will be
+moved out of the class 'Data'.)
+
+Conceptually, the definition of the @gmap@ combinators in terms of the
+primitive 'gfoldl' requires the identification of the 'gfoldl' function
+arguments. Technically, we also need to identify the type constructor
+@c@ for the construction of the result type from the folded term type.
+
+In the definition of @gmapQ@/x/ combinators, we use phantom type
+constructors for the @c@ in the type of 'gfoldl' because the result type
+of a query does not involve the (polymorphic) type of the term argument.
+In the definition of 'gmapQl' we simply use the plain constant type
+constructor because 'gfoldl' is left-associative anyway and so it is
+readily suited to fold a left-associative binary operation over the
+immediate subterms. In the definition of gmapQr, extra effort is
+needed. We use a higher-order accumulation trick to mediate between
+left-associative constructor application vs. right-associative binary
+operation (e.g., @(:)@). When the query is meant to compute a value
+of type @r@, then the result type withing generic folding is @r -> r@.
+So the result of folding is a function to which we finally pass the
+right unit.
+
+With the @-fglasgow-exts@ option, GHC can generate instances of the
+'Data' class automatically. For example, given the declaration
+
+> data T a b = C1 a b | C2 deriving (Typeable, Data)
+
+GHC will generate an instance that is equivalent to
+
+> instance (Data a, Data b) => Data (T a b) where
+> gfoldl k z (C1 a b) = z C1 `k` a `k` b
+> gfoldl k z C2 = z C2
+>
+> gunfold k z c = case constrIndex c of
+> 1 -> k (k (z C1))
+> 2 -> z C2
+>
+> toConstr (C1 _ _) = con_C1
+> toConstr C2 = con_C2
+>
+> dataTypeOf _ = ty_T
+>
+> con_C1 = mkConstr ty_T "C1" [] Prefix
+> con_C2 = mkConstr ty_T "C2" [] Prefix
+> ty_T = mkDataType "Module.T" [con_C1, con_C2]
+
+This is suitable for datatypes that are exported transparently.
-}
class Typeable a => Data a where
-{-
-
-Folding constructor applications ("gfoldl")
-
-The combinator takes two arguments "f" and "z" to fold over a term
-"x". The result type is defined in terms of "x" but variability is
-achieved by means of type constructor "c" for the construction of the
-actual result type. The purpose of the argument "z" is to define how
-the empty constructor application is folded. So "z" is like the
-neutral / start element for list folding. The purpose of the argument
-"f" is to define how the nonempty constructor application is
-folded. That is, "f" takes the folded "tail" of the constructor
-application and its head, i.e., an immediate subterm, and combines
-them in some way. See the Data instances in this file for an
-illustration of "gfoldl". Conclusion: the type of gfoldl is a
-headache, but operationally it is simple generalisation of a list
-fold.
-
--}
-
- -- | Left-associative fold operation for constructor applications
+ -- | Left-associative fold operation for constructor applications.
+ --
+ -- The type of 'gfoldl' is a headache, but operationally it is a simple
+ -- generalisation of a list fold.
+ --
+ -- The default definition for 'gfoldl' is @'const' 'id'@, which is
+ -- suitable for abstract datatypes with no substructures.
gfoldl :: (forall a b. Data a => c (a -> b) -> a -> c b)
+ -- ^ defines how nonempty constructor applications are
+ -- folded. It takes the folded tail of the constructor
+ -- application and its head, i.e., an immediate subterm,
+ -- and combines them in some way.
-> (forall g. g -> c g)
- -> a -> c a
+ -- ^ defines how the empty constructor application is
+ -- folded, like the neutral \/ start element for list
+ -- folding.
+ -> a
+ -- ^ structure to be folded.
+ -> c a
+ -- ^ result, with a type defined in terms of @a@, but
+ -- variability is achieved by means of type constructor
+ -- @c@ for the construction of the actual result type.
+
+ -- See the 'Data' instances in this file for an illustration of 'gfoldl'.
- -- Default definition for gfoldl
- -- which copes immediately with basic datatypes
- --
gfoldl _ z = z
+ -- | Unfolding constructor applications
+ gunfold :: (forall b r. Data b => c (b -> r) -> c r)
+ -> (forall r. r -> c r)
+ -> Constr
+ -> c a
+
-- | Obtaining the constructor from a given datum.
-- For proper terms, this is meant to be the top-level constructor.
-- Primitive datatypes are here viewed as potentially infinite sets of
-- values (i.e., constructors).
- --
toConstr :: a -> Constr
- -- | Building a term from a constructor
- fromConstr :: Constr -> a
-
-
- -- | Provide access to list of all constructors
+ -- | The outer type constructor of the type
dataTypeOf :: a -> DataType
--
------------------------------------------------------------------------------
- -- | Mediate types and unary type constructors
- cast0to1 :: Typeable1 t
- => (forall a. Data a => c (t a))
- -> Maybe (c a)
- cast0to1 _ = Nothing
-
- -- | Mediate types and binary type constructors
- cast0to2 :: Typeable2 t
- => (forall a b. (Data a, Data b) => c (t a b))
- -> Maybe (c a)
- cast0to2 _ = Nothing
+ -- | Mediate types and unary type constructors.
+ -- In 'Data' instances of the form @T a@, 'dataCast1' should be defined
+ -- as 'gcast1'.
+ --
+ -- The default definition is @'const' 'Nothing'@, which is appropriate
+ -- for non-unary type constructors.
+ dataCast1 :: Typeable1 t
+ => (forall a. Data a => c (t a))
+ -> Maybe (c a)
+ dataCast1 _ = Nothing
+
+ -- | Mediate types and binary type constructors.
+ -- In 'Data' instances of the form @T a b@, 'dataCast2' should be
+ -- defined as 'gcast2'.
+ --
+ -- The default definition is @'const' 'Nothing'@, which is appropriate
+ -- for non-binary type constructors.
+ dataCast2 :: Typeable2 t
+ => (forall a b. (Data a, Data b) => c (t a b))
+ -> Maybe (c a)
+ dataCast2 _ = Nothing
--
------------------------------------------------------------------------------
-{-
-
-The combinators gmapT, gmapQ, gmapM, ... can all be defined in terms
-of gfoldl. We provide corresponding default definitions leaving open
-the opportunity to provide datatype-specific definitions.
-
-(The inclusion of the gmap combinators as members of class Data allows
-the programmer or the compiler to derive specialised, and maybe more
-efficient code per datatype. Note: gfoldl is more higher-order than
-the gmap combinators. This is subject to ongoing benchmarking
-experiments. It might turn out that the gmap combinators will be moved
-out of the class Data.)
-
-Conceptually, the definition of the gmap combinators in terms of the
-primitive gfoldl requires the identification of the gfoldl function
-arguments. Technically, we also need to identify the type constructor
-"c" for the construction of the result type from the folded term type.
-
--}
-
-- | A generic transformation that maps over the immediate subterms
+ --
+ -- The default definition instantiates the type constructor @c@ in the
+ -- type of 'gfoldl' to an identity datatype constructor, using the
+ -- isomorphism pair as injection and projection.
gmapT :: (forall b. Data b => b -> b) -> a -> a
-- Use an identity datatype constructor ID (see below)
k c x = CONST $ (unCONST c) `o` f x
z _ = CONST r
-{-
-
-In the definition of gmapQ? combinators, we use phantom type
-constructors for the "c" in the type of "gfoldl" because the result
-type of a query does not involve the (polymorphic) type of the term
-argument. In the definition of gmapQl we simply use the plain constant
-type constructor because gfoldl is left-associative anyway and so it
-is readily suited to fold a left-associative binary operation over the
-immediate subterms. In the definition of gmapQr, extra effort is
-needed. We use a higher-order accumulation trick to mediate between
-left-associative constructor application vs. right-associative binary
-operation (e.g., (:)). When the query is meant to compute a value of
-type r, then the result type withing generic folding is r -> r. So the
-result of folding is a function to which we finally pass the right
-unit.
-
--}
-
-- | A generic query with a right-associative binary operator
gmapQr :: (r' -> r -> r) -> r -> (forall a. Data a => a -> r') -> a -> r
gmapQr o r f x = unQr (gfoldl k (const (Qr id)) x) r
-- | A generic query that processes the immediate subterms and returns a list
+ -- of results. The list is given in the same order as originally specified
+ -- in the declaratoin of the data constructors.
gmapQ :: (forall a. Data a => a -> u) -> a -> [u]
gmapQ f = gmapQr (:) [] f
-- | A generic monadic transformation that maps over the immediate subterms
+ --
+ -- The default definition instantiates the type constructor @c@ in
+ -- the type of 'gfoldl' to the monad datatype constructor, defining
+ -- injection and projection using 'return' and '>>='.
gmapM :: Monad m => (forall a. Data a => a -> m a) -> a -> m a
-- Use immediately the monad datatype constructor
------------------------------------------------------------------------------
--
+-- Generic unfolding
+--
+------------------------------------------------------------------------------
+
+
+-- | Build a term skeleton
+fromConstr :: Data a => Constr -> a
+fromConstr = fromConstrB undefined
+
+
+-- | Build a term and use a generic function for subterms
+fromConstrB :: Data a
+ => (forall a. Data a => a)
+ -> Constr
+ -> a
+fromConstrB f = unID . gunfold k z
+ where
+ k c = ID (unID c f)
+ z = ID
+
+
+-- | Monadic variation on 'fromConstrB'
+fromConstrM :: (Monad m, Data a)
+ => (forall a. Data a => m a)
+ -> Constr
+ -> m a
+fromConstrM f = gunfold k z
+ where
+ k c = do { c' <- c; b <- f; return (c' b) }
+ z = return
+
+
+
+------------------------------------------------------------------------------
+--
-- Datatype and constructor representations
--
------------------------------------------------------------------------------
--
-- | Representation of datatypes.
--- | A package of constructor representations with names of type and module.
--- | The list of constructors could be an array, a balanced tree, or others.
+-- A package of constructor representations with names of type and module.
--
data DataType = DataType
{ tycon :: String
-- | Representation of constructors
data Constr = Constr
- { conrep :: ConRep
+ { conrep :: ConstrRep
, constring :: String
+ , confields :: [String] -- for AlgRep only
, confixity :: Fixity -- for AlgRep only
, datatype :: DataType
}
-- | Equality of constructors
instance Eq Constr where
- c == c' = conRep c == conRep c'
+ c == c' = constrRep c == constrRep c'
-- | Public representation of datatypes
| NoRep
deriving (Eq,Show)
+-- The list of constructors could be an array, a balanced tree, or others.
-- | Public representation of constructors
-data ConRep = AlgCon ConIndex
- | IntCon Integer
- | FloatCon Double
- | StringCon String
+data ConstrRep = AlgConstr ConIndex
+ | IntConstr Integer
+ | FloatConstr Double
+ | StringConstr String
- deriving (Eq,Show)
+ deriving (Eq,Show)
---
--- | Unique index for datatype constructors.
--- | Textual order is respected. Starts at 1.
---
+-- | Unique index for datatype constructors,
+-- counting from 1 in the order they are given in the program text.
type ConIndex = Int
-- | Gets the type constructor including the module
-dataTypeCon :: DataType -> String
-dataTypeCon = tycon
+dataTypeName :: DataType -> String
+dataTypeName = tycon
--- | Gets the public presentation of datatypes
+-- | Gets the public presentation of a datatype
dataTypeRep :: DataType -> DataRep
dataTypeRep = datarep
-- | Gets the datatype of a constructor
-conDataType :: Constr -> DataType
-conDataType = datatype
+constrType :: Constr -> DataType
+constrType = datatype
-- | Gets the public presentation of constructors
-conRep :: Constr -> ConRep
-conRep = conrep
+constrRep :: Constr -> ConstrRep
+constrRep = conrep
-- | Look up a constructor by its representation
-repCon :: DataType -> ConRep -> Constr
-repCon dt cr =
+repConstr :: DataType -> ConstrRep -> Constr
+repConstr dt cr =
case (dataTypeRep dt, cr) of
- (AlgRep cs, AlgCon i) -> cs !! (i-1)
- (IntRep, IntCon i) -> mkIntCon dt i
- (FloatRep, FloatCon f) -> mkFloatCon dt f
- (StringRep, StringCon str) -> mkStringCon dt str
- _ -> error "repCon"
+ (AlgRep cs, AlgConstr i) -> cs !! (i-1)
+ (IntRep, IntConstr i) -> mkIntConstr dt i
+ (FloatRep, FloatConstr f) -> mkFloatConstr dt f
+ (StringRep, StringConstr str) -> mkStringConstr dt str
+ _ -> error "repConstr"
-- | Constructs a constructor
-mkDataCon :: DataType -> String -> Fixity -> Constr
-mkDataCon dt str fix =
+mkConstr :: DataType -> String -> [String] -> Fixity -> Constr
+mkConstr dt str fields fix =
Constr
- { conrep = AlgCon idx
+ { conrep = AlgConstr idx
, constring = str
+ , confields = fields
, confixity = fix
, datatype = dt
}
where
- idx = head [ i | (c,i) <- algTypeCons dt `zip` [1..],
- conString c == str ]
+ idx = head [ i | (c,i) <- dataTypeConstrs dt `zip` [1..],
+ showConstr c == str ]
+
+
+-- | Gets the constructors of an algebraic datatype
+dataTypeConstrs :: DataType -> [Constr]
+dataTypeConstrs dt = case datarep dt of
+ (AlgRep cons) -> cons
+ _ -> error "dataTypeConstrs"
--- | Gets the constructors
-algTypeCons :: DataType -> [Constr]
-algTypeCons dt = case datarep dt of
- (AlgRep cons) -> cons
- _ -> error "algTypeCons"
+-- | Gets the field labels of a constructor. The list of labels
+-- is returned in the same order as they were given in the original
+-- constructor declaration.
+constrFields :: Constr -> [String]
+constrFields = confields
-- | Gets the fixity of a constructor
-conFixity :: Constr -> Fixity
-conFixity = confixity
+constrFixity :: Constr -> Fixity
+constrFixity = confixity
-- | Gets the string for a constructor
-conString :: Constr -> String
-conString = constring
+showConstr :: Constr -> String
+showConstr = constring
-- | Lookup a constructor via a string
-stringCon :: DataType -> String -> Maybe Constr
-stringCon dt str =
+readConstr :: DataType -> String -> Maybe Constr
+readConstr dt str =
case dataTypeRep dt of
AlgRep cons -> idx cons
- IntRep -> mkReadCon (\i -> (mkPrimCon dt str (IntCon i)))
- FloatRep -> mkReadCon (\f -> (mkPrimCon dt str (FloatCon f)))
- StringRep -> Just (mkStringCon dt str)
+ IntRep -> mkReadCon (\i -> (mkPrimCon dt str (IntConstr i)))
+ FloatRep -> mkReadCon (\f -> (mkPrimCon dt str (FloatConstr f)))
+ StringRep -> Just (mkStringConstr dt str)
NoRep -> Nothing
where
-- Traverse list of algebraic datatype constructors
idx :: [Constr] -> Maybe Constr
- idx cons = let fit = filter ((==) str . conString) cons
+ idx cons = let fit = filter ((==) str . showConstr) cons
in if fit == []
then Nothing
else Just (head fit)
_ -> False
--- | Gets the constructor for an index
-indexCon :: DataType -> ConIndex -> Constr
-indexCon dt idx = case datarep dt of
- (AlgRep cs) -> cs !! (idx-1)
- _ -> error "indexCon"
+-- | Gets the constructor for an index (algebraic datatypes only)
+indexConstr :: DataType -> ConIndex -> Constr
+indexConstr dt idx = case datarep dt of
+ (AlgRep cs) -> cs !! (idx-1)
+ _ -> error "indexConstr"
--- | Gets the index of a constructor
-conIndex :: Constr -> ConIndex
-conIndex con = case conRep con of
- (AlgCon idx) -> idx
- _ -> error "conIndex"
+-- | Gets the index of a constructor (algebraic datatypes only)
+constrIndex :: Constr -> ConIndex
+constrIndex con = case constrRep con of
+ (AlgConstr idx) -> idx
+ _ -> error "constrIndex"
--- | Gets the maximum constructor index
-maxConIndex :: DataType -> ConIndex
-maxConIndex dt = case dataTypeRep dt of
- AlgRep cs -> length cs
- _ -> error "maxConIndex"
+-- | Gets the maximum constructor index of an algebraic datatype
+maxConstrIndex :: DataType -> ConIndex
+maxConstrIndex dt = case dataTypeRep dt of
+ AlgRep cs -> length cs
+ _ -> error "maxConstrIndex"
------------------------------------------------------------------------------
--- | Constructs the Int type
+-- | Constructs the 'Int' type
mkIntType :: String -> DataType
mkIntType = mkPrimType IntRep
--- | Constructs the Float type
+-- | Constructs the 'Float' type
mkFloatType :: String -> DataType
mkFloatType = mkPrimType FloatRep
--- | Constructs the String type
+-- | Constructs the 'String' type
mkStringType :: String -> DataType
mkStringType = mkPrimType StringRep
--- | Helper for mkIntType, mkFloatType, mkStringType
+-- | Helper for 'mkIntType', 'mkFloatType', 'mkStringType'
mkPrimType :: DataRep -> String -> DataType
mkPrimType dr str = DataType
{ tycon = str
-- Makes a constructor for primitive types
-mkPrimCon :: DataType -> String -> ConRep -> Constr
+mkPrimCon :: DataType -> String -> ConstrRep -> Constr
mkPrimCon dt str cr = Constr
{ datatype = dt
, conrep = cr
, constring = str
- , confixity = error "conFixity"
+ , confields = error "constrFields"
+ , confixity = error "constrFixity"
}
-mkIntCon :: DataType -> Integer -> Constr
-mkIntCon dt i = case datarep dt of
- IntRep -> mkPrimCon dt (show i) (IntCon i)
- _ -> error "mkIntCon"
+mkIntConstr :: DataType -> Integer -> Constr
+mkIntConstr dt i = case datarep dt of
+ IntRep -> mkPrimCon dt (show i) (IntConstr i)
+ _ -> error "mkIntConstr"
-mkFloatCon :: DataType -> Double -> Constr
-mkFloatCon dt f = case datarep dt of
- FloatRep -> mkPrimCon dt (show f) (FloatCon f)
- _ -> error "mkFloatCon"
+mkFloatConstr :: DataType -> Double -> Constr
+mkFloatConstr dt f = case datarep dt of
+ FloatRep -> mkPrimCon dt (show f) (FloatConstr f)
+ _ -> error "mkFloatConstr"
-mkStringCon :: DataType -> String -> Constr
-mkStringCon dt str = case datarep dt of
- StringRep -> mkPrimCon dt str (StringCon str)
- _ -> error "mkStringCon"
+mkStringConstr :: DataType -> String -> Constr
+mkStringConstr dt str = case datarep dt of
+ StringRep -> mkPrimCon dt str (StringConstr str)
+ _ -> error "mkStringConstr"
------------------------------------------------------------------------------
------------------------------------------------------------------------------
--- | Constructs a non-representation
+-- | Constructs a non-representation for a non-presentable type
mkNorepType :: String -> DataType
mkNorepType str = DataType
{ tycon = str
------------------------------------------------------------------------------
--- | Gets the unqualified type constructor
--- Drop *.*.*... before name
+-- | Gets the unqualified type constructor:
+-- drop *.*.*... before name
--
tyconUQname :: String -> String
tyconUQname x = let x' = dropWhile (not . (==) '.') x
in if x' == [] then x else tyconUQname (tail x')
--- | Gets the module of a type constructor
--- Take *.*.*... before name
+-- | Gets the module of a type constructor:
+-- take *.*.*... before name
tyconModule :: String -> String
tyconModule x = let (a,b) = break ((==) '.') x
in if b == ""