163 lines
11 KiB
Plaintext
163 lines
11 KiB
Plaintext
Patterns in AVAP
|
||
In AVAP, patterns provide a powerful way to match and destructure values. Patterns can be used in match statements to perform complex value comparisons and deconstructions. Here is a description of the available patterns and how they are used:
|
||
|
||
Literal Patterns: Match specific literal values such as numbers, strings, or booleans. For example:
|
||
match value: case 10: # Code to execute if value is 10 case "hello": # Code to execute if value is "hello"
|
||
Variable Patterns: Capture the value of a variable. This allows you to use the matched value in the corresponding case block:
|
||
match value: case x: # Code to execute, x will be assigned the value
|
||
Sequence Patterns: Match sequences like lists or tuples. You can also use the * operator to capture remaining elements:
|
||
match value: case [1, 2, *rest]: # Code to execute, rest will capture any additional elements
|
||
Mapping Patterns: Match dictionaries or similar mappings by specifying keys and their corresponding patterns:
|
||
match value: case "key": 42: # Code to execute if the dictionary has "key" with value 42
|
||
Class Patterns: Match instances of classes. You can also match specific attributes within the instance:
|
||
match value: case MyClass(attr1=42): # Code to execute if value is an instance of MyClass with attr1 equal to 42
|
||
Patterns in AVAP offer a flexible approach for handling different kinds of data structures and values, making it easier to write expressive and maintainable code.
|
||
|
||
OR Patterns
|
||
An OR pattern in AVAP allows you to specify multiple patterns separated by vertical bars (|). The OR pattern attempts to match each of its subpatterns with the subject value in order. If any of the subpatterns match, the OR pattern is considered successful. If none of the subpatterns match, the OR pattern fails.
|
||
|
||
or_pattern ::= "|".closed_pattern+
|
||
Here's how you can use OR patterns in practice:
|
||
|
||
match value: case 1 | 2 | 3: # Code to execute if value is 1, 2, or 3 case "hello" | "world": # Code to execute if value is "hello" or "world" case _: # Code to execute if value does not match any of the above
|
||
In this example:
|
||
|
||
The first case will match if value is either 1, 2, or 3.
|
||
The second case will match if value is either "hello" or "world".
|
||
The last case is a catch-all pattern that will execute if none of the previous patterns match.
|
||
OR patterns provide a concise way to handle multiple possible values or types, simplifying pattern matching and making your code more readable.
|
||
|
||
AS Patterns
|
||
An AS pattern in AVAP is used to bind an OR pattern to a name. This allows you to match a value with an OR pattern and simultaneously capture it under a specified name for further use. The syntax for an AS pattern is:
|
||
|
||
as_pattern ::= or_pattern "as" capture_pattern
|
||
When an AS pattern is used, if the OR pattern succeeds, the subject is bound to the name specified by the capture pattern, and the AS pattern itself succeeds.
|
||
|
||
Here's an example of how to use AS patterns:
|
||
|
||
match value: case 1 | 2 | 3 as x: print(f"Matched a number: x") case "hello" | "world" as greeting: print(f"Matched a greeting: greeting") case _: print("No match")
|
||
In this example:
|
||
|
||
The first case matches if value is 1, 2, or 3. The matched value is bound to the name x, which is then used in the print statement.
|
||
The second case matches if value is "hello" or "world". The matched value is bound to the name greeting, which is then used in the print statement.
|
||
The last case is a catch-all pattern that executes if none of the previous patterns match.
|
||
AS patterns are useful for capturing matched values under a name while using OR patterns, allowing for more flexible and readable pattern matching in your code.
|
||
|
||
Literal Patterns
|
||
In AVAP, literal patterns are used to match specific literal values, such as numbers, strings, or boolean values. The syntax for a literal pattern is:
|
||
|
||
literal_pattern ::= signed_number | strings | "None" | "True" | "False"
|
||
A literal pattern only succeeds if the value of the subject is equal to the specified literal value.
|
||
|
||
Here are examples of literal patterns and their usage:
|
||
|
||
match value: case 42: print("Matched the number 42") case "hello": print("Matched the string 'hello'") case None: print("Matched None") case True: print("Matched True") case False: print("Matched False") case _: print("No match")
|
||
In this example:
|
||
|
||
case 42: matches if value is exactly 42.
|
||
case "hello": matches if value is the string "hello".
|
||
case None: matches if value is None.
|
||
case True: matches if value is True.
|
||
case False: matches if value is False.
|
||
case _: is a catch-all pattern that executes if none of the previous patterns match.
|
||
Literal patterns are useful for matching specific, known values and are a fundamental part of pattern matching in AVAP.
|
||
|
||
Capture Patterns
|
||
In AVAP, capture patterns are used to bind the subject's value to a name. The syntax for a capture pattern is:
|
||
|
||
capture_pattern ::= NAME
|
||
Capture patterns always succeed and bind the value of the subject to the specified name.
|
||
|
||
Here’s how you might use capture patterns in AVAP:
|
||
|
||
match value: case x: print(f"Captured value: x")
|
||
In this example:
|
||
|
||
case x: captures whatever value is in value and binds it to the name x. The pattern always succeeds.
|
||
Capture patterns are useful when you want to extract and use the value of the subject within your code, regardless of what that value is.
|
||
|
||
Wildcard Patterns
|
||
In AVAP, wildcard patterns are used to match any value without binding it to a name. The syntax for a wildcard pattern is:
|
||
|
||
wildcard_pattern ::= '_'
|
||
Wildcard patterns always succeed and do not create any bindings. They are useful when you want to ignore the value of the subject and only care about whether it matches a certain pattern.
|
||
|
||
Here’s how you might use wildcard patterns in AVAP:
|
||
|
||
match value: case _: print("Matched any value")
|
||
In this example:
|
||
|
||
case _: matches any value and does not bind it to a name. The pattern always succeeds, and the code within this case will be executed regardless of the value.
|
||
Wildcard patterns are particularly useful when you need to handle a broad range of possibilities and are only interested in whether a value fits a general condition, not in the value itself.
|
||
|
||
Value Patterns
|
||
In AVAP, value patterns are used to match specific values. The syntax for a value pattern is:
|
||
|
||
value_pattern ::= attr
|
||
Value patterns only succeed if the subject's value matches the specified value. They are useful when you want to perform actions based on an exact value.
|
||
|
||
Here’s how you might use value patterns in AVAP:
|
||
|
||
match value: case 42: print("Matched the value 42") case "hello": print("Matched the string 'hello'") case _: print("Matched something else")
|
||
In this example:
|
||
|
||
case 42: matches the value 42 specifically.
|
||
case "hello": matches the string "hello" specifically.
|
||
case _: matches any other value not covered by the previous cases.
|
||
Value patterns are ideal for scenarios where you need to check for specific values and respond accordingly. They provide precise control over the matching process.
|
||
|
||
Group Patterns
|
||
In AVAP, group patterns are used to group multiple patterns together. The syntax for a group pattern is:
|
||
|
||
group_pattern ::= "(" pattern ")"
|
||
Group patterns are useful when you want to combine patterns or when patterns need to be evaluated together. They have the same effect as the pattern they contain but allow for more complex pattern structures.
|
||
|
||
Here’s an example of how to use group patterns in AVAP:
|
||
|
||
match value: case (42 | 43): print("Matched either 42 or 43") case (name, age) if age > 18: print(f" is an adult") case _: print("Matched something else")
|
||
In this example:
|
||
|
||
case (42 | 43): uses a group pattern to match either the value 42 or 43.
|
||
case (name, age) if age > 18: uses a group pattern to match a tuple and includes an additional condition on the age.
|
||
case _: matches any other value not covered by the previous cases.
|
||
Group patterns are ideal for creating more complex matching scenarios where patterns need to be combined or grouped together.
|
||
|
||
Sequence Patterns
|
||
In AVAP, sequence patterns are used to match elements within sequences like lists or tuples. The syntax for sequence patterns is:
|
||
|
||
sequence_pattern ::= "[" [maybe_sequence_pattern] "]" | "(" [open_sequence_pattern] ")"
|
||
Sequence patterns can match elements of sequences based on specific rules. Here’s how they work:
|
||
|
||
List Patterns: Use square brackets [ ] to match lists. You can include patterns for the elements within the list.
|
||
case [a, b, c]: print("Matched a list with three elements")
|
||
Tuple Patterns: Use parentheses ( ) to match tuples. Similarly, you can specify patterns for the tuple elements.
|
||
case (x, y): print("Matched a tuple with two elements")
|
||
Sequence patterns allow for flexible and powerful matching of sequence types. They can match sequences of various lengths and structures by defining the pattern for each element.
|
||
|
||
Here’s an example of using sequence patterns in a match statement:
|
||
|
||
match value: case [1, 2, 3]: print("Matched a list with elements 1, 2, 3") case (a, b, c) if a + b == c: print("Matched a tuple where a + b equals c") case _: print("Matched something else")
|
||
In this example:
|
||
|
||
case [1, 2, 3]: matches a list with exactly the elements 1, 2, and 3.
|
||
case (a, b, c) if a + b == c: matches a tuple and includes a condition to check if a + b equals c.
|
||
case _: matches any other value not covered by the previous cases.
|
||
Mapping Patterns
|
||
In AVAP, mapping patterns are used to match mapping elements, such as dictionaries. Here is the syntax and behavior of mapping patterns:
|
||
|
||
mapping_pattern ::= { [items_pattern] }
|
||
Mapping Patterns are designed to match elements within mappings, such as dictionaries. They use specific rules to determine if a pattern matches the given mapping.
|
||
|
||
Syntax: Mapping patterns are enclosed in curly braces { ... }. The items_pattern specifies the pattern for the mapping items.
|
||
Matching Rules: The rules for matching mapping patterns include checking for key-value pairs in the mapping and ensuring they align with the specified pattern.
|
||
Usage: Mapping patterns are useful for destructuring dictionaries and other mapping types in a concise manner.
|
||
Mapping patterns enhance pattern matching capabilities by allowing for specific and flexible matching of dictionary elements.
|
||
|
||
Class Patterns
|
||
In AVAP, class patterns are used to match instances of specific classes. Here is a detailed overview:
|
||
|
||
class_pattern ::= name "(" [pattern_arguments ","?] ")"
|
||
Pattern Syntax: A class pattern specifies the class name followed by a parenthesized list of pattern_arguments. The pattern matches instances of the specified class.
|
||
Matching Instances: The pattern will match if the subject is an instance of the specified class and the pattern_arguments (if any) match according to the rules defined for the pattern.
|
||
Usage: Class patterns are useful for deconstructing objects based on their class and extracting values from them, enabling more precise pattern matching.
|
||
These patterns provide a way to work with objects based on their class type and structure, facilitating more sophisticated pattern matching and value extraction. |