Active Patterns are now available in Kit v2026.3.7 and later. Inspired by F#'s active patterns, this feature enables powerful, reusable pattern matching logic.
We're excited to announce that Active Patterns have arrived in Kit! This powerful feature, inspired by F#'s active patterns, allows you to define reusable, composable pattern matching logic that integrates seamlessly with Kit's existing match expressions.
What Are Active Patterns?
Active patterns are functions that participate in pattern matching. Unlike regular patterns that match on structure, active patterns can execute arbitrary logic to determine if a value matches, and can extract and transform values in the process.
An active pattern function returns Option T:
-
Some extracted_value- The pattern matches, andextracted_valueis bound to the pattern variable None- The pattern doesn't match, and the next pattern is tried
Defining Active Patterns
Use the pattern keyword to define an active pattern:
# Define a pattern that matches positive numbers
pattern positive = fn(n) =>
if n > 0 then Some n else None
# Define a pattern that matches even numbers
pattern even = fn(n) =>
if n % 2 == 0 then Some n else None
# Define a pattern that matches values in a specific range
pattern in-range = fn(min, max, n) =>
if n >= min and n <= max then Some n else None
Using Active Patterns
Active patterns work in match expressions just like built-in patterns:
# Use active patterns in match expressions
classify = fn(n) =>
match n
| positive x -> "${x} is positive"
| _ -> "not positive"
println (classify 42) # => 42 is positive
println (classify -5) # => not positive
AND Pattern Composition
One of the most powerful features of active patterns is the ability to compose them with the
and
keyword. This allows you to require multiple patterns to match simultaneously:
pattern small = fn(n) =>
if n < 10 then Some n else None
# Both patterns must match, both variables are bound
result = match 5
| positive x and small y -> x + y
| _ -> 0
println result # => 10 (5 + 5)
In this example:
positive 5returnsSome 5, so x is bound to 5small 5returnsSome 5, so y is also bound to 5- Both patterns match, so the expression
x + yevaluates to 10
Value Extraction and Transformation
Active patterns can do more than just match - they can extract and transform values:
# Pattern that doubles the matched value
pattern double-it = fn(n) => Some (n * 2)
# Pattern that extracts the first character of a string
pattern first-char = fn(s) =>
if String.length s > 0 then Some (String.char-at s 0) else None
result = match 7
| double-it x -> x
| _ -> 0
println result # => 14
Practical Examples
Validation
pattern valid-age = fn(age) =>
if age >= 0 and age <= 150 then Some age else None
pattern adult = fn(age) =>
if age >= 18 then Some age else None
check-person = fn(age) =>
match age
| valid-age a and adult _ -> "Valid adult: ${a}"
| valid-age a -> "Valid minor: ${a}"
| _ -> "Invalid age"
String Parsing
pattern digit = fn(c) =>
if c >= "0" and c <= "9" then Some c else None
pattern vowel = fn(c) =>
vowels = ["a", "e", "i", "o", "u"]
if List.contains? vowels c then Some c else None
Implementation Status
Active Patterns are now fully implemented in Kit v2026.3.7:
- Parser: Full support for
patternkeyword and pattern expressions - Type Checking: Validates that patterns return
Option T - IL Lowering: Pattern calls are properly lowered to IL instructions
- Interpreter: Full runtime support via IL interpretation
- Compiler: Native code generation support
- AND Patterns: Complete support for pattern composition with variable binding
Next Steps
Ready to try Active Patterns? Check out the documentation:
Active patterns open up new possibilities for clean, reusable pattern matching in Kit. We're excited to see what you build with them!