diff options
Diffstat (limited to 'js/baba-yaga/docs/03_pattern-matching.md')
-rw-r--r-- | js/baba-yaga/docs/03_pattern-matching.md | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/js/baba-yaga/docs/03_pattern-matching.md b/js/baba-yaga/docs/03_pattern-matching.md new file mode 100644 index 0000000..0bd663e --- /dev/null +++ b/js/baba-yaga/docs/03_pattern-matching.md @@ -0,0 +1,133 @@ +# Pattern Matching + +The `when` expression matches a discriminant against patterns. + +## Literals and Wildcards +```baba +describe : x -> + when x is + 0 then "Zero" + 1 then "One" + _ then "Other"; +``` + +## Multiple Discriminants +```baba +whereIs : x y -> + when x y is + 0 0 then "Origin" + 1 1 then "Diagonal" + _ _ then "Somewhere"; +``` + +## Type Patterns +```baba +checkType : val -> + when val is + Int then "Integer" + String then "String" + Bool then "Boolean" + _ then "Other"; +``` + +## Pattern Guards + +Use the `if` keyword to add conditional guards to patterns: + +```baba +// Basic guards with range conditions +categorizeNumber : n -> + when n is + x if (x > 0) then "positive" + x if (x < 0) then "negative" + 0 then "zero"; + +// Guards with complex conditions +gradeStudent : score -> + when score is + s if (s >= 90) then "A" + s if (s >= 80 and s < 90) then "B" + s if (s >= 70 and s < 80) then "C" + s if (s >= 60 and s < 70) then "D" + s if (s < 60) then "F" + _ then "Invalid score"; + +// Type guards +processValue : value -> + when value is + Int if value > 100 then "large integer" + Int if value > 0 then "positive integer" + String if (length value) > 10 then "long string" + String if (length value) > 0 then "short string" + _ then "other"; + +// Guards with wildcard patterns +checkRange : x -> + when x is + _ if (x >= 1 and x <= 10) then "small" + _ if (x >= 11 and x <= 100) then "medium" + _ if (x > 100) then "large" + _ then "invalid"; +``` + +Guards are evaluated after the underlying pattern matches. The guard expression has access to any variables bound by the pattern. This allows for sophisticated conditional matching without conflicting with the `..` string concatenation operator. + +## Typed discriminants + +When using typed functions that return `Result`, you can pattern match on variants and bind inner values. + +```baba +divide : (x: Int, y: Int) -> Result -> + when y is + 0 then Err "Division by zero" + _ then Ok (x / y); + +use : r -> + when r is + Ok val then val + Err msg then msg; +``` + +## Result Patterns + +```baba +divide : x y -> + when y is + 0 then Err "Division by zero" + _ then Ok (x / y); + +use : r -> + when r is + Ok val then val + Err msg then msg; +``` + +## Using `with` alongside `when` + +Use `with` to stage named locals used by discriminants and consequents. + +```baba +classify : n -> + with (lo Int; hi Int; lo : 10; hi : 100;) -> + when n is + 0 then "zero" + _ then when (n > hi) is + true then "large" + _ then when (n > lo) is + true then "medium" + _ then "small"; +``` + +## List & Table Patterns + +```baba +is123 : xs -> + when xs is + [1, 2, 3] then true + _ then false; + +hasA1B2 : t -> + when t is + { a: 1, b: 2 } then true + _ then false; +``` |