1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
.. _record-wildcards:
Record wildcards
----------------
.. extension:: RecordWildCards
:shortdesc: Enable record wildcards.
Implies :extension:`DisambiguateRecordFields`.
:implies: :extension:`DisambiguateRecordFields`.
:since: 6.8.1
Allow the use of wildcards in record construction and pattern matching.
Record wildcards are enabled by the language extension :extension:`RecordWildCards`. This
extension implies :extension:`DisambiguateRecordFields`.
For records with many fields, it can be tiresome to write out each field
individually in a record pattern, as in ::
data C = C {a :: Int, b :: Int, c :: Int, d :: Int}
f (C {a = 1, b = b, c = c, d = d}) = b + c + d
Record wildcard syntax permits a "``..``" in a record pattern, where
each elided field ``f`` is replaced by the pattern ``f = f``. For
example, the above pattern can be written as ::
f (C {a = 1, ..}) = b + c + d
More details:
- Record wildcards in patterns can be mixed with other patterns,
including puns (:ref:`record-puns`); for example, in a pattern
``(C {a = 1, b, ..})``. Additionally, record wildcards can be used
wherever record patterns occur, including in ``let`` bindings and at
the top-level. For example, the top-level binding ::
C {a = 1, ..} = e
defines ``b``, ``c``, and ``d``.
- Record wildcards can also be used in an expression, when constructing
a record. For example, ::
let {a = 1; b = 2; c = 3; d = 4} in C {..}
in place of ::
let {a = 1; b = 2; c = 3; d = 4} in C {a=a, b=b, c=c, d=d}
The expansion is purely syntactic, so the record wildcard expression
refers to the nearest enclosing variables that are spelled the same
as the omitted field names.
- For both pattern and expression wildcards, the "``..``" expands to
the missing *in-scope* record fields. Specifically the expansion of
"``C {..}``" includes ``f`` if and only if:
- ``f`` is a record field of constructor ``C``.
- The record field ``f`` is in scope somehow (either qualified or
unqualified).
These rules restrict record wildcards to the situations in which the
user could have written the expanded version. For example ::
module M where
data R = R { a,b,c :: Int }
module X where
import M( R(R,a,c) )
f a b = R { .. }
The ``R{..}`` expands to ``R{a=a}``, omitting ``b`` since the
record field is not in scope, and omitting ``c`` since the variable
``c`` is not in scope (apart from the binding of the record selector
``c``, of course).
- When record wildcards are used in record construction, a field ``f``
is initialised only if ``f`` is in scope,
and is not imported or bound at top level.
For example, ``f`` can be bound by an enclosing pattern match or
let/where-binding. For example ::
module M where
import A( a )
data R = R { a,b,c,d :: Int }
c = 3 :: Int
f b = R { .. } -- Expands to R { b = b, d = d }
where
d = b+1
Here, ``a`` is imported, and ``c`` is bound at top level, so neither
contribute to the expansion of the "``..``".
The motivation here is that it should be
easy for the reader to figure out what the "``..``" expands to.
- Record wildcards cannot be used (a) in a record update construct, and
(b) for data constructors that are not declared with record fields.
For example: ::
f x = x { v=True, .. } -- Illegal (a)
data T = MkT Int Bool
g = MkT { .. } -- Illegal (b)
h (MkT { .. }) = True -- Illegal (b)
|