match

ALFA supports match expressions on 3 types of values:

  1. Primitive values
  2. Enum values
  3. Tagged Union - fields

Primitive value match

Syntax

match <primitive-value-holder> {
    <primitive-value1>   ->   <case1-result>
    <primitive-value2>   ->   <case2-result>
    <primitive-value3>   ->   <case3-result>
    <else>    <else-result>
}

The usage can be easily understood looking at an example.

intToDayName( i : int ) : string {
    return match i {
        1 -> "Monday"
        2 -> "Tuesday"
        3 -> "Wednesday"
        4 -> "Thursday"
        5 -> "Friday"
        6 -> "Saturday"
        7 -> "Sunday"
        else ""
    }
}

Value’s Type-based matching

Syntax

match <user-type-value-holder> {
    <variable-name> : <type-name1>   ->   <case1-result>
    <variable-name> : <type-name2>   ->   <case1-result>
    <variable-name> : <type-name3>   ->   <case1-result>
    <else>    <else-result>
}

The usage can be easily understood from an example.

Each ‘case’ is a variable and its associated type - e.g. t:Train, where t is the variable and Train is the type. The value of the variable, t, is only accessible in the scope on the right-hand side expression.

travelTime( transport : Transport, distanceKm : int ) : double {
    return match transport {
        f:Flight -> f.checkinDuration  + ( distanceKm / 800 )
        t:Train  -> t.stopOverDuration + ( distanceKm / 200 )
        c:Car    -> distanceKm / 60
        f:Ferry  -> f.landTravelTime + ( distanceKm / 30 )
        else        NaN
    }
}

Union field based matching

Syntax

match <union-value-holder> {
    <variable-name> : <union-field1>   ->   <case1-result>
    <variable-name> : <union-field2>   ->   <case1-result>
    <variable-name> : <union-field3>   ->   <case1-result>
    <else>    <else-result>
}

When <union-value-holder> is a union, the identifier right of the : is a union field name.

The usage can be easily understood from an example.

union Transaction {
    Card : CardPayment
    Transfer : BankTransfer
    Cash : CashWithdrawal
}

calculateFee( t : Transaction ) : double {
    return match t {
        c : Card     -> c.transactionTotal * 0.02   // 2%
        t : Transfer -> 0.1                         // flat fee
        c : Cash     -> 0
    }
}