-----------------------------------------------------------------------------
-- |
-- Module : Data.Generics.Instances
-- Copyright : (c) The University of Glasgow, CWI 2001--2004
-- License : BSD-style (see the file libraries/base/LICENSE)
--
-- Maintainer : libraries@haskell.org
-- Stability : experimental
-- Portability : non-portable (uses Data.Generics.Basics)
--
-- \"Scrap your boilerplate\" --- Generic programming in Haskell
-- See <http://www.cs.vu.nl/boilerplate/>. The present module
-- instantiates the class Data for Prelude-like datatypes.
-- (This module does not export anything. It really just defines instances.)
--
-----------------------------------------------------------------------------
module Data.Generics.Instances
where
------------------------------------------------------------------------------
#ifdef __HADDOCK__
import Prelude
#endif
import Data.Generics.Basics
import Data.Typeable
import Data.Int -- So we can give Data instance for Int8, ...
import Data.Word -- So we can give Data instance for Word8, ...
import GHC.Real( Ratio(..) ) -- So we can give Data instance for Ratio
import GHC.IOBase -- So we can give Data instance for IO, Handle
import GHC.Ptr -- So we can give Data instance for Ptr
import GHC.ForeignPtr -- So we can give Data instance for ForeignPtr
import GHC.Stable -- So we can give Data instance for StablePtr
import GHC.ST -- So we can give Data instance for ST
import GHC.Conc -- So we can give Data instance for MVar & Co.
import GHC.Arr -- So we can give Data instance for Array
#include "Typeable.h"
------------------------------------------------------------------------------
--
-- Instances of the Data class for Prelude-like types.
-- We define top-level definitions for representations.
--
------------------------------------------------------------------------------
falseConstr = mkConstr boolDataType "False" [] Prefix
trueConstr = mkConstr boolDataType "True" [] Prefix
boolDataType = mkDataType "Prelude.Bool" [falseConstr,trueConstr]
instance Data Bool where
toConstr False = falseConstr
toConstr True = trueConstr
gunfold k z c = case constrIndex c of
1 -> z False
2 -> z True
_ -> error "gunfold"
dataTypeOf _ = boolDataType
------------------------------------------------------------------------------
charType = mkStringType "Prelude.Char"
instance Data Char where
toConstr x = mkStringConstr charType [x]
gunfold k z c = case constrRep c of
(StringConstr [x]) -> z x
_ -> error "gunfold"
dataTypeOf _ = charType
------------------------------------------------------------------------------
floatType = mkFloatType "Prelude.Float"
instance Data Float where
toConstr x = mkFloatConstr floatType (realToFrac x)
gunfold k z c = case constrRep c of
(FloatConstr x) -> z (realToFrac x)
_ -> error "gunfold"
dataTypeOf _ = floatType
------------------------------------------------------------------------------
doubleType = mkFloatType "Prelude.Double"
instance Data Double where
toConstr = mkFloatConstr floatType
gunfold k z c = case constrRep c of
(FloatConstr x) -> z x
_ -> error "gunfold"
dataTypeOf _ = doubleType
------------------------------------------------------------------------------
intType = mkIntType "Prelude.Int"
instance Data Int where
toConstr x = mkIntConstr intType (fromIntegral x)
gunfold k z c = case constrRep c of
(IntConstr x) -> z (fromIntegral x)
_ -> error "gunfold"
dataTypeOf _ = intType
------------------------------------------------------------------------------
integerType = mkIntType "Prelude.Integer"
instance Data Integer where
toConstr = mkIntConstr integerType
gunfold k z c = case constrRep c of
(IntConstr x) -> z x
_ -> error "gunfold"
dataTypeOf _ = integerType
------------------------------------------------------------------------------
int8Type = mkIntType "Data.Int.Int8"
instance Data Int8 where
toConstr x = mkIntConstr int8Type (fromIntegral x)
gunfold k z c = case constrRep c of
(IntConstr x) -> z (fromIntegral x)
_ -> error "gunfold"
dataTypeOf _ = int8Type
------------------------------------------------------------------------------
int16Type = mkIntType "Data.Int.Int16"
instance Data Int16 where
toConstr x = mkIntConstr int16Type (fromIntegral x)
gunfold k z c = case constrRep c of
(IntConstr x) -> z (fromIntegral x)
_ -> error "gunfold"
dataTypeOf _ = int16Type
------------------------------------------------------------------------------
int32Type = mkIntType "Data.Int.Int32"
instance Data Int32 where
toConstr x = mkIntConstr int32Type (fromIntegral x)
gunfold k z c = case constrRep c of
(IntConstr x) -> z (fromIntegral x)
_ -> error "gunfold"
dataTypeOf _ = int32Type
------------------------------------------------------------------------------
int64Type = mkIntType "Data.Int.Int64"
instance Data Int64 where
toConstr x = mkIntConstr int64Type (fromIntegral x)
gunfold k z c = case constrRep c of
(IntConstr x) -> z (fromIntegral x)
_ -> error "gunfold"
dataTypeOf _ = int64Type
------------------------------------------------------------------------------
wordType = mkIntType "Data.Word.Word"
instance Data Word where
toConstr x = mkIntConstr wordType (fromIntegral x)
gunfold k z c = case constrRep c of
(IntConstr x) -> z (fromIntegral x)
_ -> error "gunfold"
dataTypeOf _ = wordType
------------------------------------------------------------------------------
word8Type = mkIntType "Data.Word.Word8"
instance Data Word8 where
toConstr x = mkIntConstr word8Type (fromIntegral x)
gunfold k z c = case constrRep c of
(IntConstr x) -> z (fromIntegral x)
_ -> error "gunfold"
dataTypeOf _ = word8Type
------------------------------------------------------------------------------
word16Type = mkIntType "Data.Word.Word16"
instance Data Word16 where
toConstr x = mkIntConstr word16Type (fromIntegral x)
gunfold k z c = case constrRep c of
(IntConstr x) -> z (fromIntegral x)
_ -> error "gunfold"
dataTypeOf _ = word16Type
------------------------------------------------------------------------------
word32Type = mkIntType "Data.Word.Word32"
instance Data Word32 where
toConstr x = mkIntConstr word32Type (fromIntegral x)
gunfold k z c = case constrRep c of
(IntConstr x) -> z (fromIntegral x)
_ -> error "gunfold"
dataTypeOf _ = word32Type
------------------------------------------------------------------------------
word64Type = mkIntType "Data.Word.Word64"
instance Data Word64 where
toConstr x = mkIntConstr word64Type (fromIntegral x)
gunfold k z c = case constrRep c of
(IntConstr x) -> z (fromIntegral x)
_ -> error "gunfold"
dataTypeOf _ = word64Type
------------------------------------------------------------------------------
ratioConstr = mkConstr ratioDataType ":%" [] Infix
ratioDataType = mkDataType "GHC.Real.Ratio" [ratioConstr]
instance (Data a, Integral a) => Data (Ratio a) where
toConstr _ = ratioConstr
gunfold k z c | constrIndex c == 1 = k (k (z (:%)))
gunfold _ _ _ = error "gunfold"
dataTypeOf _ = ratioDataType
------------------------------------------------------------------------------
nilConstr = mkConstr listDataType "[]" [] Prefix
consConstr = mkConstr listDataType "(:)" [] Infix
listDataType = mkDataType "Prelude.[]" [nilConstr,consConstr]
instance Data a => Data [a] where
gfoldl f z [] = z []
gfoldl f z (x:xs) = z (:) `f` x `f` xs
toConstr [] = nilConstr
toConstr (_:_) = consConstr
gunfold k z c = case constrIndex c of
1 -> z []
2 -> k (k (z (:)))
_ -> error "gunfold"
dataTypeOf _ = listDataType
dataCast1 f = gcast1 f
--
-- The gmaps are given as an illustration.
-- This shows that the gmaps for lists are different from list maps.
--
gmapT f [] = []
gmapT f (x:xs) = (f x:f xs)
gmapQ f [] = []
gmapQ f (x:xs) = [f x,f xs]
gmapM f [] = return []
gmapM f (x:xs) = f x >>= \x' -> f xs >>= \xs' -> return (x':xs')
------------------------------------------------------------------------------
nothingConstr = mkConstr maybeDataType "Nothing" [] Prefix
justConstr = mkConstr maybeDataType "Just" [] Prefix
maybeDataType = mkDataType "Prelude.Maybe" [nothingConstr,justConstr]
instance Data a => Data (Maybe a) where
gfoldl f z Nothing = z Nothing
gfoldl f z (Just x) = z Just `f` x
toConstr Nothing = nothingConstr
toConstr (Just _) = justConstr
gunfold k z c = case constrIndex c of
1 -> z Nothing
2 -> k (z Just)
_ -> error "gunfold"
dataTypeOf _ = maybeDataType
dataCast1 f = gcast1 f
------------------------------------------------------------------------------
ltConstr = mkConstr orderingDataType "LT" [] Prefix
eqConstr = mkConstr orderingDataType "EQ" [] Prefix
gtConstr = mkConstr orderingDataType "GT" [] Prefix
orderingDataType = mkDataType "Prelude.Ordering" [ltConstr,eqConstr,gtConstr]
instance Data Ordering where
gfoldl f z LT = z LT
gfoldl f z EQ = z EQ
gfoldl f z GT = z GT
toConstr LT = ltConstr
toConstr EQ = eqConstr
toConstr GT = gtConstr
gunfold k z c = case constrIndex c of
1 -> z LT
2 -> z EQ
3 -> z GT
_ -> error "gunfold"
dataTypeOf _ = orderingDataType
------------------------------------------------------------------------------
leftConstr = mkConstr eitherDataType "Left" [] Prefix
rightConstr = mkConstr eitherDataType "Right" [] Prefix
eitherDataType = mkDataType "Prelude.Either" [leftConstr,rightConstr]
instance (Data a, Data b) => Data (Either a b) where
gfoldl f z (Left a) = z Left `f` a
gfoldl f z (Right a) = z Right `f` a
toConstr (Left _) = leftConstr
toConstr (Right _) = rightConstr
gunfold k z c = case constrIndex c of
1 -> k (z Left)
2 -> k (z Right)
_ -> error "gunfold"
dataTypeOf _ = eitherDataType
dataCast2 f = gcast2 f
------------------------------------------------------------------------------
--
-- A last resort for functions
--
instance (Data a, Data b) => Data (a -> b) where
toConstr _ = error "toConstr"
gunfold _ _ = error "gunfold"
dataTypeOf _ = mkNorepType "Prelude.(->)"
dataCast2 f = gcast2 f
------------------------------------------------------------------------------
tuple0Constr = mkConstr tuple0DataType "()" [] Prefix
tuple0DataType = mkDataType "Prelude.()" [tuple0Constr]
instance Data () where
toConstr () = tuple0Constr
gunfold k z c | constrIndex c == 1 = z ()
gunfold _ _ _ = error "gunfold"
dataTypeOf _ = tuple0DataType
------------------------------------------------------------------------------
tuple2Constr = mkConstr tuple2DataType "(,)" [] Infix
tuple2DataType = mkDataType "Prelude.(,)" [tuple2Constr]
instance (Data a, Data b) => Data (a,b) where
gfoldl f z (a,b) = z (,) `f` a `f` b
toConstr (a,b) = tuple2Constr
gunfold k z c | constrIndex c == 1 = k (k (z (,)))
gunfold _ _ _ = error "gunfold"
dataTypeOf _ = tuple2DataType
dataCast2 f = gcast2 f
------------------------------------------------------------------------------
tuple3Constr = mkConstr tuple3DataType "(,,)" [] Infix
tuple3DataType = mkDataType "Prelude.(,)" [tuple3Constr]
instance (Data a, Data b, Data c) => Data (a,b,c) where
gfoldl f z (a,b,c) = z (,,) `f` a `f` b `f` c
toConstr (a,b,c) = tuple3Constr
gunfold k z c | constrIndex c == 1 = k (k (k (z (,,))))
gunfold _ _ _ = error "gunfold"
dataTypeOf _ = tuple3DataType
------------------------------------------------------------------------------
tuple4Constr = mkConstr tuple4DataType "(,,,)" [] Infix
tuple4DataType = mkDataType "Prelude.(,,,)" [tuple4Constr]
instance (Data a, Data b, Data c, Data d)
=> Data (a,b,c,d) where
gfoldl f z (a,b,c,d) = z (,,,) `f` a `f` b `f` c `f` d
toConstr (a,b,c,d) = tuple4Constr
gunfold k z c = case constrIndex c of
1 -> k (k (k (k (z (,,,)))))
_ -> error "gunfold"
dataTypeOf _ = tuple4DataType
------------------------------------------------------------------------------
tuple5Constr = mkConstr tuple5DataType "(,,,,)" [] Infix
tuple5DataType = mkDataType "Prelude.(,,,,)" [tuple5Constr]
instance (Data a, Data b, Data c, Data d, Data e)
=> Data (a,b,c,d,e) where
gfoldl f z (a,b,c,d,e) = z (,,,,) `f` a `f` b `f` c `f` d `f` e
toConstr (a,b,c,d,e) = tuple5Constr
gunfold k z c = case constrIndex c of
1 -> k (k (k (k (k (z (,,,,))))))
_ -> error "gunfold"
dataTypeOf _ = tuple5DataType
------------------------------------------------------------------------------
tuple6Constr = mkConstr tuple6DataType "(,,,,,)" [] Infix
tuple6DataType = mkDataType "Prelude.(,,,,,)" [tuple6Constr]
instance (Data a, Data b, Data c, Data d, Data e, Data f)
=> Data (a,b,c,d,e,f) where
gfoldl f z (a,b,c,d,e,f') = z (,,,,,) `f` a `f` b `f` c `f` d `f` e `f` f'
toConstr (a,b,c,d,e,f) = tuple6Constr
gunfold k z c = case constrIndex c of
1 -> k (k (k (k (k (k (z (,,,,,)))))))
_ -> error "gunfold"
dataTypeOf _ = tuple6DataType
------------------------------------------------------------------------------
tuple7Constr = mkConstr tuple7DataType "(,,,,,,)" [] Infix
tuple7DataType = mkDataType "Prelude.(,,,,,,)" [tuple7Constr]
instance (Data a, Data b, Data c, Data d, Data e, Data f, Data g)
=> Data (a,b,c,d,e,f,g) where
gfoldl f z (a,b,c,d,e,f',g) =
z (,,,,,,) `f` a `f` b `f` c `f` d `f` e `f` f' `f` g
toConstr (a,b,c,d,e,f,g) = tuple7Constr
gunfold k z c = case constrIndex c of
1 -> k (k (k (k (k (k (k (z (,,,,,,))))))))
_ -> error "gunfold"
dataTypeOf _ = tuple7DataType
------------------------------------------------------------------------------
instance Data TypeRep where
toConstr _ = error "toConstr"
gunfold _ _ = error "gunfold"
dataTypeOf _ = mkNorepType "Data.Typeable.TypeRep"
------------------------------------------------------------------------------
instance Data TyCon where
toConstr _ = error "toConstr"
gunfold _ _ = error "gunfold"
dataTypeOf _ = mkNorepType "Data.Typeable.TyCon"
------------------------------------------------------------------------------
INSTANCE_TYPEABLE0(DataType,dataTypeTc,"DataType")
instance Data DataType where
toConstr _ = error "toConstr"
gunfold _ _ = error "gunfold"
dataTypeOf _ = mkNorepType "Data.Generics.Basics.DataType"
------------------------------------------------------------------------------
instance Typeable a => Data (IO a) where
toConstr _ = error "toConstr"
gunfold _ _ = error "gunfold"
dataTypeOf _ = mkNorepType "GHC.IOBase.IO"
------------------------------------------------------------------------------
instance Data Handle where
toConstr _ = error "toConstr"
gunfold _ _ = error "gunfold"
dataTypeOf _ = mkNorepType "GHC.IOBase.Handle"
------------------------------------------------------------------------------
instance Typeable a => Data (Ptr a) where
toConstr _ = error "toConstr"
gunfold _ _ = error "gunfold"
dataTypeOf _ = mkNorepType "GHC.Ptr.Ptr"
------------------------------------------------------------------------------
instance Typeable a => Data (StablePtr a) where
toConstr _ = error "toConstr"
gunfold _ _ = error "gunfold"
dataTypeOf _ = mkNorepType "GHC.Stable.StablePtr"
------------------------------------------------------------------------------
instance Typeable a => Data (IORef a) where
toConstr _ = error "toConstr"
gunfold _ _ = error "gunfold"
dataTypeOf _ = mkNorepType "GHC.IOBase.IORef"
------------------------------------------------------------------------------
instance Typeable a => Data (ForeignPtr a) where
toConstr _ = error "toConstr"
gunfold _ _ = error "gunfold"
dataTypeOf _ = mkNorepType "GHC.ForeignPtr.ForeignPtr"
------------------------------------------------------------------------------
instance (Typeable s, Typeable a) => Data (ST s a) where
toConstr _ = error "toConstr"
gunfold _ _ = error "gunfold"
dataTypeOf _ = mkNorepType "GHC.ST.ST"
------------------------------------------------------------------------------
instance Data ThreadId where
toConstr _ = error "toConstr"
gunfold _ _ = error "gunfold"
dataTypeOf _ = mkNorepType "GHC.Conc.ThreadId"
------------------------------------------------------------------------------
instance Typeable a => Data (TVar a) where
toConstr _ = error "toConstr"
gunfold _ _ = error "gunfold"
dataTypeOf _ = mkNorepType "GHC.Conc.TVar"
------------------------------------------------------------------------------
instance Typeable a => Data (MVar a) where
toConstr _ = error "toConstr"
gunfold _ _ = error "gunfold"
dataTypeOf _ = mkNorepType "GHC.Conc.MVar"
------------------------------------------------------------------------------
instance Typeable a => Data (STM a) where
toConstr _ = error "toConstr"
gunfold _ _ = error "gunfold"
dataTypeOf _ = mkNorepType "GHC.Conc.STM"
------------------------------------------------------------------------------
-- The Data instance for Array preserves data abstraction at the cost of inefficiency.
-- We omit reflection services for the sake of data abstraction.
instance (Typeable a, Data b, Ix a) => Data (Array a b)
where
gfoldl f z a = z (listArray (bounds a)) `f` (elems a)
toConstr _ = error "toConstr"
gunfold _ _ = error "gunfold"
dataTypeOf _ = mkNorepType "Data.Array.Array"
|