Makefiles need real tab chars, ffs.
[packages/dph.git] / dph-lifted-copy / Data / Array / Parallel / PArray / Types.hs
1 {-# LANGUAGE EmptyDataDecls #-}
2
3 -- | Defines the extra types we use when representing algebraic data in parallel arrays.
4 -- We don't store values of user defined algebraic type directly in PArrays. Instead,
5 -- we convert these to a generic representation and store that representation.
6 --
7 -- Conversion to and from the generic representation is handled by the methods
8 -- of the PA class defined in "Data.Array.Parallel.PArray.PRepr".
9 --
10 --- For further information see:
11 -- "Instant Generics: Fast and Easy", Chakravarty, Ditu and Keller, 2009
12 --
13 module Data.Array.Parallel.PArray.Types (
14 -- * The Void type
15 Void,
16 void,
17 fromVoid,
18
19 -- * Generic sums
20 Sum2(..),
21 Sum3(..),
22
23 -- * The Wrap type
24 Wrap (..)
25 )
26 where
27
28 -- Void -----------------------------------------------------------------------
29 -- | The `Void` type is used when representing enumerations.
30 -- A type like Bool is represented as @Sum2 Void Void@, meaning that we only
31 -- only care about the tag of the data constructor and not its argumnent.
32 data Void
33
34 -- | A 'value' with the void type. Used as a placholder like `undefined`.
35 -- Forcing this yields `error`.
36 void :: Void
37 void = error $ unlines
38 [ "Data.Array.Parallel.PArray.Types.void"
39 , " With the DPH generic array representation, values of type void"
40 , " should never be forced. Something has gone badly wrong." ]
41
42
43 -- | Coerce a `Void` to a different type. Used as a placeholder like `undefined`.
44 -- Forcing the result yields `error`.
45 fromVoid :: a
46 fromVoid = error $unlines
47 [ "Data.Array.Parallel.PArray.Types.fromVoid"
48 , " With the DPH generic array representation, values of type void"
49 , " should never be forced. Something has gone badly wrong." ]
50
51
52 -- Sums -----------------------------------------------------------------------
53 -- | Sum types used for the generic representation of algebraic data.
54 data Sum2 a b = Alt2_1 a | Alt2_2 b
55 data Sum3 a b c = Alt3_1 a | Alt3_2 b | Alt3_3 c
56
57
58 -- Wrap -----------------------------------------------------------------------
59 -- | When converting a data type to its generic representation, we use
60 -- `Wrap` to help us convert only one layer at a time. For example:
61 --
62 -- @
63 -- data Foo a = Foo Int a
64 --
65 -- instance PA a => PA (Foo a) where
66 -- type PRepr (Foo a) = (Int, Wrap a) -- define how (Foo a) is represented
67 -- @
68 --
69 -- Here we've converted the @Foo@ data constructor to a pair, and Int
70 -- is its own representation type. We have PData/PR instances for pairs and
71 -- Ints, so we can work with arrays of these types. However, we can't just
72 -- use (Int, a) as the representation of (Foo a) because 'a' might
73 -- be user defined and we won't have PData/PR instances for it.
74 --
75 -- Instead, we wrap the second element with the Wrap constructor, which tells
76 -- us that if we want to process this element we still need to convert it
77 -- to the generic representation (and back). This last part is done by
78 -- the PR instance of Wrap, who's methods are defined by calls to the *PD
79 -- functions from "Data.Array.Parallel.PArray.PRepr".
80 --
81 newtype Wrap a = Wrap { unWrap :: a }
82
83
84