Skip to content

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

blossom
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

blossom
age -> {
    0..17  => "Minor",
    18..65 => "Adult",
    _      => "Senior"
}

blossom
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

blossom
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

blossom
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

blossom
GetDiscountRate :: (age: Int) : Float -> {
    match age -> {
        0      => 0.0
        1..17  => 0.25
        18..65 => 0.0
        _      => 0.15
    }
}

Destructuring

blossom
+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:

blossom
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:

blossom
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 |:

blossom
IsWeekend :: (day: String) : Bool -> {
    match day -> {
        "Saturday" | "Sunday" => True
        _ => False
    }
}