This is pattern matching. From the link:
Functions may be composed of one or more rules. A rule consists of its function-name, an argument pattern and its expression. When the function is called the argument values will be matched to the patterns in top down order. Functions using pattern-matching are very similar to case expressions
This means the pipe separates cases for pattern matching. Pattern matching matches special patterns and executes specific expressions based on that pattern. They follow the syntax:
fun <fun-name> <pattern>
| <fun-name> <pattern>
| <fun-name> <pattern>;
Where <pattern>
is:
<args> = <expressions>
In your first example, it is declaring function fac
for factorial calculation. The first pattern is when the argument, int
is 0. If int
is 0, the expression of that case will execute, and in this case if the passed argument is 0, the result will be 1 (because 0 factorial is 1). If the passed argument is not 0 then it follows the next pattern (as it did not match the first pattern). If the passed argument is, say 2, it will perform recursion and find the factorial accordingly.
Consider the snippet below:
fun past "run" = "ran"
| past "swim" = "swam"
| past x = x ^ "ed";
We define function named past
that takes an argument and finds the passed tense of the argument. The first pattern is equivalent to - in plain English:
if the word (or passed argument) is "run", the passed tense is "ran".
The second pattern is equivalent to:
if the word (or passed argument) is "swim", the passed tense is "swam".
If the word is neither "swim" or "run" (and thus the two patterns are not matched) continue with the last pattern, which just adds "ed" to the end of the word.
With the example you can see that |
(pipe) symbols separate patterns. You can think of patterns like this pseudocode:
if argument is "run", then passed tense is "ran"
else if argument is "swim", then passed tense is "swam"
else add "ed" to end of word
Pattern matching is used to cover irregular cases. Since "ran" and "swam" are irregular passed tenses, we cover those cases with patterns. The exact same principle applies to the first example - 0! is a special case, it is 1. Because of this, we can use pattern matching to match the specific case where the argument is 0 and execute according to that specific case.