generic-deriving-0.4: src/Generics/Deriving/Base.hs
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE CPP #-}
module Generics.Deriving.Base (
#ifndef __UHC__
-- * Generic representation types
V1, U1(..), Par1(..), Rec1(..), K1(..), M1(..)
, (:+:)(..), (:*:)(..), (:.:)(..)
-- ** Synonyms for convenience
, Rec0, Par0, R, P
, D1, C1, S1, D, C, S
-- * Meta-information
, Datatype(..), Constructor(..), Selector(..), NoSelector
, Fixity(..), Associativity(..), Arity(..), prec
-- * Representable type classes
, Representable0(..), Representable1(..)
,
#else
module UHC.Generics,
#endif
) where
#ifdef __UHC__
import UHC.Generics
#endif
#ifndef __UHC__
--------------------------------------------------------------------------------
-- Representation types
--------------------------------------------------------------------------------
-- | Void: used for datatypes without constructors
#ifdef __UHC__
V1 :: * -> *
#endif
data V1 p
-- | Unit: used for constructors without arguments
#ifdef __UHC__
U1 :: * -> *
#endif
data U1 p = U1
-- | Used for marking occurrences of the parameter
#ifdef __UHC__
Par1 :: * -> *
#endif
newtype Par1 p = Par1 { unPar1 :: p }
-- | Recursive calls of kind * -> *
#ifdef __UHC__
Rec1 :: (* -> *) -> * -> *
#endif
newtype Rec1 f p = Rec1 { unRec1 :: f p }
-- | Constants, additional parameters and recursion of kind *
#ifdef __UHC__
K1 :: * -> * -> * -> *
#endif
newtype K1 i c p = K1 { unK1 :: c }
-- | Meta-information (constructor names, etc.)
#ifdef __UHC__
M1 :: * -> * -> (* -> *) -> * -> *
#endif
newtype M1 i c f p = M1 { unM1 :: f p }
-- | Sums: encode choice between constructors
infixr 5 :+:
#ifdef __UHC__
(:+:) :: (* -> *) -> (* -> *) -> * -> *
#endif
data (:+:) f g p = L1 { unL1 :: f p } | R1 { unR1 :: g p }
-- | Products: encode multiple arguments to constructors
infixr 6 :*:
#ifdef __UHC__
(:*:) :: (* -> *) -> (* -> *) -> * -> *
#endif
data (:*:) f g p = f p :*: g p
-- | Composition of functors
infixr 7 :.:
#ifdef __UHC__
(:.:) :: (* -> *) -> (* -> *) -> * -> *
#endif
newtype (:.:) f g p = Comp1 { unComp1 :: f (g p) }
-- | Tag for K1: recursion (of kind *)
data R
-- | Tag for K1: parameters (other than the last)
data P
-- | Type synonym for encoding recursion (of kind *)
type Rec0 = K1 R
-- | Type synonym for encoding parameters (other than the last)
type Par0 = K1 P
-- | Tag for M1: datatype
data D
-- | Tag for M1: constructor
data C
-- | Tag for M1: record selector
data S
-- | Type synonym for encoding meta-information for datatypes
type D1 = M1 D
-- | Type synonym for encoding meta-information for constructors
type C1 = M1 C
-- | Type synonym for encoding meta-information for record selectors
type S1 = M1 S
-- | Class for datatypes that represent datatypes
class Datatype d where
-- | The name of the datatype, fully qualified
#ifdef __UHC__
datatypeName :: t d f a -> String
moduleName :: t d f a -> String
#else
datatypeName :: t d (f :: * -> *) a -> String
moduleName :: t d (f :: * -> *) a -> String
#endif
-- | Class for datatypes that represent records
class Selector s where
-- | The name of the selector
#ifdef __UHC__
selName :: t s f a -> String
#else
selName :: t s (f :: * -> *) a -> String
#endif
-- | Used for constructor fields without a name
data NoSelector
instance Selector NoSelector where selName _ = ""
-- | Class for datatypes that represent data constructors
class Constructor c where
-- | The name of the constructor
#ifdef __UHC__
conName :: t c f a -> String
#else
conName :: t c (f :: * -> *) a -> String
#endif
-- | The fixity of the constructor
#ifdef __UHC__
conFixity :: t c f a -> Fixity
#else
conFixity :: t c (f :: * -> *) a -> Fixity
#endif
conFixity = const Prefix
-- | Marks if this constructor is a record
#ifdef __UHC__
conIsRecord :: t c f a -> Bool
#else
conIsRecord :: t c (f :: * -> *) a -> Bool
#endif
conIsRecord = const False
-- | Marks if this constructor is a tuple,
-- returning arity >=0 if so, <0 if not
#ifdef __UHC__
conIsTuple :: t c f a -> Arity
#else
conIsTuple :: t c (f :: * -> *) a -> Arity
#endif
conIsTuple = const NoArity
-- | Datatype to represent the arity of a tuple.
data Arity = NoArity | Arity Int
deriving (Eq, Show, Ord, Read)
-- | Datatype to represent the fixity of a constructor. An infix
-- | declaration directly corresponds to an application of 'Infix'.
data Fixity = Prefix | Infix Associativity Int
deriving (Eq, Show, Ord, Read)
-- | Get the precedence of a fixity value.
prec :: Fixity -> Int
prec Prefix = 10
prec (Infix _ n) = n
-- | Datatype to represent the associativy of a constructor
data Associativity = LeftAssociative
| RightAssociative
| NotAssociative
deriving (Eq, Show, Ord, Read)
-- | Representable types of kind *
class Representable0 a rep where
-- | Convert from the datatype to its representation
from0 :: a -> rep x
-- | Convert from the representation to the datatype
to0 :: rep x -> a
-- | Representable types of kind * -> *
class Representable1 f rep where
-- | Convert from the datatype to its representation
from1 :: f a -> rep a
-- | Convert from the representation to the datatype
to1 :: rep a -> f a
#endif