[project @ 2002-08-28 11:29:42 by simonpj]
[ghc-hetmet.git] / ghc / docs / comm / the-beast / data-types.html
1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
2 <html>
3   <head>
4     <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1">
5     <title>The GHC Commentary - Data types and data constructors</title>
6   </head>
7
8   <body BGCOLOR="FFFFFF">
9     <h1>The GHC Commentary - Data types and data constructors</h1>
10     <p>
11
12
13 <h2>Data types</h2>
14
15 Consider the following data type declaration:
16
17 <pre>
18   data T a = MkT !(a,a) !(T a) | Nil
19 </pre>
20 The user's source program mentions only the constructors <tt>MkT</tt>
21 and <tt>Nil</tt>.  However, these constructors actually <em>do</em> something
22 in addition to building a data value.  For a start, <tt>MkT</tt> evaluates
23 its arguments.  Secondly, with the flag <tt>-funbox-strict-fields</tt> GHC
24 will flatten (or unbox) the strict fields.  So GHC generates a top-level function
25 for each data constructor, as follows:
26
27 <pre>
28   MkT :: (a,a) -> T a -> T a
29   MkT p t = case p of 
30               (a,b) -> seq t ($wMkT a b t)
31
32   Nil :: T a
33   Nil = $wNil
34 </pre>
35
36 Here, the <em>wrapper</em> <tt>MkT</tt> evaluates and takes the argument <tt>p</tt>,
37 evaluates the argument <tt>t</tt>, and builds a three-field data value
38 with the <em>worker</em> constructor <tt>$wMKT</tt>.  (There are more notes below
39 about the unboxing of strict fields.)
40 <p>
41 So the original constructors, <tt>MkT</tt> and <tt>Nil</tt> are really just
42 <em>wrappers</em> which perhaps do some work before calling the <em>workers</em>
43 <tt>$wMkT</tt> and <tt>$wNil</tt>.  The workers are 
44 the "representation constructors" of
45 the "representation data type", which we can think of as being defined thus:
46
47 <pre>
48   data T a = $wMkT a a Int | $wNil
49 </pre>
50
51 This representation data type, gives the number and types of
52 fields of the constructors used to represent values of type <tt>T</tt>.
53 This representation type is also what is emitted when you print External Core 
54 from GHC.  
55
56 <h3> The constructor wrapper functions </h3>
57
58 The wrapper functions are automatically generated by GHC, and are
59 really emitted into the result code (albeit only after CorePre; see
60 <tt>CorePrep.mkImplicitBinds</tt>).  
61 The wrapper functions are inlined very
62 vigorously, so you will not see many occurrences of the wrapper
63 functions in an optimised program, but you may see some.  For example,
64 if your Haskell source has
65 <pre>
66     map MkT xs
67 </pre>
68 then <tt>MkT</tt> will not be inlined (because it is not applied to anything).
69 That is why we generate real top-level bindings for the wrapper functions,
70 and generate code for them.
71
72
73 <h3> Unboxing strict fields </h3>
74
75 If GHC unboxes strict fields (as in the first argument of <tt>MkT</tt> above), 
76 it also transforms
77 source-language case expressions.  Suppose you write this in your Haskell source:
78 <pre>
79    case e of 
80      MkT p t -> ..p..t..
81 </pre>
82 GHC will desugar this to the following Core code:
83 <pre>
84    case e of
85      $wMkT a b t -> let p = (a,b) in ..p..t..
86 </pre>
87 (<em>Important note</em>: perhaps misleadingly, when printing Core we
88 actually print the constructor in the case expression as
89 "<tt>MkT</tt>" not as "<tt>$wMkT</tt>", but it really means the
90 latter.)
91 <p>
92 The local let-binding reboxes the pair because it may be mentioned in
93 the case alternative.  This may well be a bad idea, which is why
94 <tt>-funbox-strict-fields</tt> is an experimental feature.
95 <p>
96 It's essential that when importing a type <tt>T</tt> defined in some
97 external module <tt>M</tt>, GHC knows what representation was used for
98 that type, and that in turn depends on whether module <tt>M</tt> was
99 compiled with <tt>-funbox-strict-fields</tt>.  So when writing an
100 interface file, GHC therefore records with each data type whether its
101 strict fields (if any) should be unboxed.
102 <p>
103   </body>
104 </html>
105