Further updates to dataspacePatterns
This commit is contained in:
parent
56d9d3e89d
commit
e4d0be69ba
|
@ -19,7 +19,14 @@ corresponds to a (possibly-nested) [binding pattern](#binding) in the overall pa
|
||||||
Consider the pattern:
|
Consider the pattern:
|
||||||
|
|
||||||
```preserves
|
```preserves
|
||||||
<arr {0:<lit 1> 1:<bind <arr {0:<bind <_>> 1:<_>}>> 2:<_>}>
|
<group <arr> {
|
||||||
|
0: <lit 1>
|
||||||
|
1: <bind <group <arr> {
|
||||||
|
0: <bind <_>>
|
||||||
|
1: <_>
|
||||||
|
}>>
|
||||||
|
2: <_>
|
||||||
|
}>
|
||||||
```
|
```
|
||||||
|
|
||||||
Each of the following values yields different results when matched against it:
|
Each of the following values yields different results when matched against it:
|
||||||
|
@ -39,41 +46,36 @@ Each of the following values yields different results when matched against it:
|
||||||
|
|
||||||
## Abstract syntax of patterns
|
## Abstract syntax of patterns
|
||||||
|
|
||||||
A *pattern* may be either a *discard*, a (nested) *binding*, a *literal*, or a *compound*.
|
A *pattern* may be either a *discard*, a (nested) *binding*, a *literal*, or a *group* (compound).
|
||||||
|
|
||||||
```preserves-schema
|
```preserves-schema
|
||||||
Pattern = DDiscard / DBind / DLit / DCompound .
|
Pattern =
|
||||||
|
/ @discard <_>
|
||||||
|
/ <bind @pattern Pattern>
|
||||||
|
/ <lit @value AnyAtom>
|
||||||
|
/ <group @type GroupType @entries { any: Pattern ...:... }>
|
||||||
|
.
|
||||||
```
|
```
|
||||||
|
|
||||||
### Discard
|
### Discard
|
||||||
|
|
||||||
A *discard pattern* matches any input value.
|
A *discard pattern*, `<_>`, matches any input value.
|
||||||
|
|
||||||
```preserves-schema
|
|
||||||
DDiscard = <_>.
|
|
||||||
```
|
|
||||||
|
|
||||||
### Binding
|
### Binding
|
||||||
|
|
||||||
A *binding pattern* speculatively pushes the portion of the input under consideration onto the
|
A *binding pattern*, `<bind ...>`, speculatively pushes the portion of the input under
|
||||||
end of the binding sequence being built, and then recursively evaluates its subpattern. If the
|
consideration onto the end of the binding sequence being built, and then recursively evaluates
|
||||||
subpattern succeeds, so does the overall binding pattern (keeping the binding); otherwise, the
|
its subpattern. If the subpattern succeeds, so does the overall binding pattern (keeping the
|
||||||
speculative addition to the binding sequence is undone, and the overall binding pattern fails.
|
binding); otherwise, the speculative addition to the binding sequence is undone, and the
|
||||||
|
overall binding pattern fails.
|
||||||
```preserves-schema
|
|
||||||
DBind = <bind @pattern Pattern>.
|
|
||||||
```
|
|
||||||
|
|
||||||
### Literal
|
### Literal
|
||||||
|
|
||||||
A *literal pattern* matches any **atomic** Preserves value. In order to match a literal
|
A *literal pattern*, `<lit ...>`, matches any **atomic** Preserves value:
|
||||||
**compound** value, a combination of compound and literal patterns must be used.
|
|
||||||
|
|
||||||
```preserves-schema
|
```preserves-schema
|
||||||
DLit = <lit @value AnyAtom>.
|
|
||||||
AnyAtom =
|
AnyAtom =
|
||||||
/ @bool bool
|
/ @bool bool
|
||||||
/ @float float
|
|
||||||
/ @double double
|
/ @double double
|
||||||
/ @int int
|
/ @int int
|
||||||
/ @string string
|
/ @string string
|
||||||
|
@ -83,39 +85,34 @@ AnyAtom =
|
||||||
.
|
.
|
||||||
```
|
```
|
||||||
|
|
||||||
### Compound
|
In order to match a literal **compound** value, a combination of group and literal patterns
|
||||||
|
must be used.
|
||||||
|
|
||||||
Each *compound pattern* first checks the type of its input: a `rec` pattern fails unless it is
|
### Group
|
||||||
given a Record, an `arr` demands a Sequence and a `dict` only matches a Dictionary.
|
|
||||||
|
Each *group pattern* first checks the type of its input: a `rec` pattern fails unless it is
|
||||||
|
given a Record having the specified `label`, an `arr` demands a Sequence and a `dict` only
|
||||||
|
matches a Dictionary.
|
||||||
|
|
||||||
```preserves-schema
|
```preserves-schema
|
||||||
DCompound = <rec @label any @fields { int: Pattern ...:... }>
|
GroupType =
|
||||||
/ <arr @items { int: Pattern ...:... }>
|
/ <rec @label any>
|
||||||
/ <dict @entries { any: Pattern ...:... }> .
|
/ <arr>
|
||||||
|
/ <dict>
|
||||||
|
.
|
||||||
```
|
```
|
||||||
|
|
||||||
If the type check fails, the pattern match fails. Otherwise, matching continues:
|
If the type check fails, the pattern match fails. Otherwise, matching continues. Subpatterns in
|
||||||
|
the `entries` field in the group pattern are considered in increasing Preserves order of
|
||||||
|
key.[^dict-pattern-ordering] For Records, each key must be a field index; for Sequences, each
|
||||||
|
key is an element index; and for Dictionaries, keys are just keys in the dictionary to be
|
||||||
|
matched. Each subpattern is matched against the corresponding portion of the input, failing if
|
||||||
|
no such item exists.
|
||||||
|
|
||||||
- `rec` patterns compare the label of the input Record against the `label` field in the
|
Group patterns ignore keys in values being matched that are not mentioned in the pattern.
|
||||||
pattern; unless they match literally and exactly, the overall match fails. Otherwise,
|
Matching succeeds if such values have *more* than the structure and information required of
|
||||||
subpatterns in `fields` are considered in increasing order of key. Each key in `fields` is
|
them by a given pattern, but not if they have less. This allows for protocol extension: for
|
||||||
the index of an input record field to examine. Each subpattern is matched against the
|
example, records with "extra" fields will continue to match.
|
||||||
corresponding field in the input, failing if no such field exists. The overall pattern thus
|
|
||||||
ignores any position in the input record for which no subpattern exists.
|
|
||||||
|
|
||||||
- `arr` patterns are similar, except without the need for a label check. Subpatterns in
|
|
||||||
`items` are processed in order of key. Each key is interpreted as an element index. Excess
|
|
||||||
or unexamined input elements are ignored.
|
|
||||||
|
|
||||||
- `dict` patterns consider each of the key/subpattern pairs in `entries` in turn, according to
|
|
||||||
the Preserves order of the keys.[^dict-pattern-ordering] If any given key from the pattern
|
|
||||||
is not present in the input value, matching fails. Otherwise, matching proceeds recursively.
|
|
||||||
The pattern ignores keys in the input value that are not mentioned in the pattern.
|
|
||||||
|
|
||||||
These rules treat Record, Sequence and Dictionary values similarly: matching will succeed if
|
|
||||||
such values have *more* than the structure and information required of them by a given pattern,
|
|
||||||
but not if they have less. This allows for protocol extension: for example, records with
|
|
||||||
"extra" fields will continue to match.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue