-
RecordWildCards -
- Подразумевает:
- С:
-
6.8.1
Разрешает использование подстановочных знаков при создании и сопоставлении с образцом записей.
Подстановочные знаки записей включаются расширением языка RecordWildCards. Это расширение подразумевает DisambiguateRecordFields.
Для записей с множеством полей может быть утомительно перечислять каждое поле индивидуально в шаблоне записи, как в
data C = C {a :: Int, b :: Int, c :: Int, d :: Int}
f (C {a = 1, b = b, c = c, d = d}) = b + c + d
Синтаксис подстановочных знаков записей допускает «..» в шаблоне записи, где каждое опушенное поле f заменяется шаблоном f = f. Например, вышеуказанный шаблон можно записать как
f (C {a = 1, ..}) = b + c + d
Дополнительные сведения:
-
Подстановочные знаки записей в шаблонах могут быть смешаны с другими шаблонами, включая каламбуры (Каламбуры записей); например, в шаблоне
(C {a = 1, b, ..}). Кроме того, подстановочные знаки записей могут использоваться везде, где встречаются шаблоны записей, в том числе вletсвязываниях и на верхнем уровне. Например, верхнеуровневое связываниеC {a = 1, ..} = eопределяет
b,c, иd. -
Подстановочные знаки записей также могут использоваться в выражении при создании записи. Например,
let {a = 1; b = 2; c = 3; d = 4} in C {..}вместо
let {a = 1; b = 2; c = 3; d = 4} in C {a=a, b=b, c=c, d=d}Расширение чисто синтаксическое, поэтому выражение с подстановочным знаком записи относится к ближайшим переменным, которые имеют то же имя, что и пропущенные имена полей.
-
Для подстановочных знаков шаблонов и выражений «
..» расширяются до отсутствующих полей записи в области видимости. В частности, расширение «C {..}» включаетfтолько в том случае, если:-
fявляется полем записи конструктораC. - Поле записи
fнаходится в области видимости каким-либо образом (как квалифицированное, так и неквалифицированное).
Эти правила ограничивают подстановочные знаки записей ситуациями, в которых пользователь мог бы написать расширенную версию. Например
module M where data R = R { a,b,c :: Int } module X where import M( R(R,a,c) ) f a b = R { .. }R{..}расширяется доR{a=a}, опускаяb, так как поле записи не находится в области видимости, и опускаяc, поскольку переменнаяcне находится в области видимости (кроме, конечно, связывания селектора записиc). -
-
При использовании подстановочных знаков записей в создании записи поле
fинициализируется только в том случае, еслиfнаходится в области видимости и не импортировано и не связано на верхнем уровне. Например,fможет быть связан путем сопоставления с образцом или связывания let/where на внешнем уровне. Например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Здесь
aимпортировано, аcсвязано на верхнем уровне, поэтому ни то, ни другое не вносят вклад в расширение «..». Здесь мотивируется то, что читателю должно быть легко понять, к чему расширяется «..». -
Подстановочные знаки записей не могут использоваться (а) в конструкции обновления записей и (б) для конструкторов данных, которые не объявлены с полями записей. Например:
f x = x { v=True, .. } -- Illegal (a) data T = MkT Int Bool g = MkT { .. } -- Illegal (b) h (MkT { .. }) = True -- Illegal (b)