Matching
Matching is one of the most important aspects of Blossom. It allows you to build sophisticated logical constructs with an elegant syntax.
Patterns
In Blossom, a pattern is a syntactic construct that describes a logical state defined by a set of constraints that an input value must meet. They are used in match expressions to determine whether an input value satisfies certain conditions and to extract or bind components from that value.
Literal
Literal patterns produce a match by comparing the currently assigned value to a literal definition.
Type(s)
All
Example
status -> {
"active" => "User is active",
"inactive" => "User is inactive",
_ => "Unknown status"
}
Range
Range patterns produce a match if a value falls within a specified range.
For numbers, this means a numerical interval. For strings, it indicates a lexicographical range.
Type(s)
Int
Float
String
Example
age -> {
0..17 => "Minor",
18..65 => "Adult",
_ => "Senior"
}
word -> {
"apple".."mango" => "Word falls in the first lexicographical range",
"mango".."zebra" => "Word falls in the second lexicographical range",
_ => "Word is out of the defined ranges"
}
Callback
Callback patterns use a function that returns a Bool
value. The callback pattern produce a match if the callback returns True
for the given value.
Example
IsComfortable :: (t: Int) : Bool -> { t >= 18 & t <= 28 }
TemperatureMessage :: (t: Int) : String -> {
t -> {
IsComfortable(t) => "Comfortable temperature",
_ => "Not comfortable"
}
}
Regex
The Regex pattern produces a match if a String
satisfies a regular expression literal, denoted using the ~
operator.
Type(s)
String
Example
email -> {
~"^[\\w.-]+@[\\w.-]+\\.\\w+$" => "Valid email",
_ => "Invalid email"
}
Hint
You can also use the Regex.Match
function for the same result.
Destructurization
Always available.
Type match
Always available.
Wildcard
Always available.
Example
GetDiscountRate :: (age: Int) : Float -> {
match age -> {
0 => 0.0
1..17 => 0.25
18..65 => 0.0
_ => 0.15
}
}
Destructuring
+Point := (Float, Float)
DescribePoint :: (p: Point) : String -> {
match p -> {
(0, 0) => "At origin"
(x, 0) => "On X axis at {x}"
(0, y) => "On Y axis at {y}"
(x, y) => "At ({x}, {y})"
}
}
Guards
Pattern matching can include guard conditions using if
:
Classify :: (n: Int) : String -> {
match n -> {
n < 0 => "Negative"
n == 0 => "Zero"
n % 2 == 0 => "Positive Even"
_ => "Positive Odd"
}
}
Type matching
You can also match types:
FindUser :: (id: String) : Optional<User> -> {
match Database.Query(id) -> {
user: User => user
_ => None
}
}
Multiple Patterns
You can match multiple patterns to the same result using |
:
IsWeekend :: (day: String) : Bool -> {
match day -> {
"Saturday" | "Sunday" => True
_ => False
}
}