module Match {
// MATCH AND PATTERN BASICS
// match is a conditional where the conditions are expressed as
// a set of patterns. patterns look like regular values but
// can also include placeholders, wildcards, and variables
// that capture values as part of matching process.
//
// multiple patterns can be specified for a given condition,
// and an optional if clause can be added to provide an
// additional constraint on the match via a boolean expression.
// The full form of a match is:
//
// match (expression) {
// pattern if condition => block; // repeats
// }
//
// MATCHING VALUES
fn test1() {
let x : int = 1;
let y = 3;
// patterns can be specific constant values, or references
// to variables or constants. use _ to match any value
// use | to specify multiple patterns to match.
match (x) {
1 | 2 | y => print("one or two or y");
_ => print("something else");
}
}
// MATCHING TYPES
fn test2() {
let x : int | string | bool = 1;
// use types as patterns to match on the type of the expression
match (x) {
string => print("string");
int => print("int");
bool => print("bool");
}
}
// CAPTURING VARIABLES
fn test3() {
// use @x : pattern to match a pattern and capture the value
// into variable x. the captured variable is scoped to the
// code after the =>.
let x : int | string | bool = 1;
// match based on type and capture the typed value
match (x) {
@a : string => print(a); // a is string
@a : int => print(a); // a is int
@a : bool => print(a); // a is bool
}
}
// MATCHING STRUCTS
struct Velocity {
dx: int;
dy: int;
}
fn test4() {
let v = Velocity(0, 1);
// use a struct pattern to match a struct.
// using _ for a field value or omitting the
// field matches all values in that field.
match (v) {
Velocity(0, 0) => print("stationary");
Velocity(dx: 0) => print("moving vertically");
Velocity(dy: 0) => print("moving horizontally");
_ => print("moving diagnonally");
}
}
// MATCHING MAPS
fn test5() {
let m = {"a" : true, "b" : false};
// use a map pattern to specify the value to match.
// omitting a key means it will be matched.
match (m) {
{"a" : @a} => print("a is ${a}");
{"a" : _, "c" : _} => print("has a and c keys");
}
}
// MATCHING ARRAYS
fn test6() {
let a = [1, true, false];
// use an array pattern to specify what to match.
// use _ to match any value in a position.
// and use ... to match the rest of the array.
match (a) {
[123, ...] => print("starts with 123");
[true, true, _] => print("array size 3 with first two values true");
[@a, @b, ...] => print("first two values are ${a}, ${b}");
}
}
// MATCH WITH IF
fn test7() {
let v = Velocity(5, 10);
// add if followed by a boolean expression the pattern
// to provide additional constraints on the match.
match (v) {
Velocity(dx : @dx, dy : @dy) if dx > 7 || dy > 7 => print("moving quickly");
Velocity(dx : @dx, dy : @dy) if dx < 3 || dy < 3 => print("moving slowly");
_ => print("moving average");
}
}
// MATCH AS AN EXPRESSION
fn test8() {
let tshirt = 1;
// match evaluates to the value of the matching expression.
let s = match (tshirt) {
1 | 2 => "small"; // this pattern matches, so s is set to "small"
3 | 4 | 5 => "medium";
_ => "large";
}
}
}