What is | character for in f #?
I'm new to functional programming and I started looking at the documentation for operators match
and in the example I found here gitpages and cut and pasted to my question below:
let rec fib n =
match n with
| 0 -> 0
| 1 -> 1
| _ -> fib (n - 1) + fib (n - 2)
I understand that let
for static binding, in this case, the recursive function is called fib which takes an n parameter. It tries to match n to 3 cases. If it's 0, 1, or whatever.
I don't understand what is the symbol being called in this context |
or why is it being used? Everything I was looking for f-sharp pipe leads me to this |>
, which is the pipe character in f sharp.
What is this |
used in this case? Is it required or not required? And when should I and should I not use |
?
source to share
The symbol is |
used for several things in F #, but in this case it serves as a construct case separator match
.
The construct match
allows you to match patterns with some inputs and treat different values ββdifferently - in your example, you have one case for 0
, one for, 1
and one for all other values.
Typically, the syntax is match
as follows:
match <input> with <case_1> | ... | <case_n>
Where each <case>
has the following structure:
<case> = <pattern> -> <expression>
Here, the symbol |
simply separates several cases of pattern matching expression. Each case has a pattern and an expression that is evaluated when the input matches the pattern.
source to share
To expand on Tomas' excellent answer, here are some more different use cases |
in F #:
Matching expressions
In expression matching , it |
separates the different patterns, as Thomas pointed out. While you can write entire expressions match
on a single line, it is common |
practice to write each pattern on a separate line, lining up the characters to display a visual indicator of the scope of the statement.match
match n with
| 0 -> "zero"
| 1 -> "one"
| 2 -> "two"
| 3 -> "three"
| _ -> "something else"
Discriminatory alliances
Discriminatory unions (or DUs, as they are much shorter than a type) are very similar to match
style expressions : defining them means enumerating possibilities, but |
used to separate possibilities. As with expressions match
, you can (if you like) write DU on one line:
type Option<'T> = None | Some of 'T
but if your DU has only two possibilities, it is usually better to write it on multiple lines:
type ContactInfo =
| Email of string
| PhoneNumber of areaCode : string * number : string
| Facebook of string
| Twitter of string
It also |
forms a vertical line here that draws attention to the capabilities of DU and makes it very clear where the definition of DU ends.
Active templates
Active templates are also used |
to separate possibilities, but they are also wrapped inside a pair of "open and close" |
symbols:
let (Even|Odd) n = if n % 2 = 0 then Even else Odd // <-- Wrong!
let (|Even|Odd|) n = if n % 2 = 0 then Even else Odd // <-- Right!
Active patterns are usually written the way I just showed, and |
they appear immediately in parentheses, which is why some people talk about "banana clips" (since pairs (|
and |)
look like bananas if you use your imagination). But in fact there is no need to write characters (|
and |)
together: it is quite right to have the gaps that separate the parentheses of the characters |
:
let (|Even|Odd|) n = if n % 2 = 0 then Even else Odd // <-- Right!
let ( |Even|Odd| ) n = if n % 2 = 0 then Even else Odd // <-- ALSO right!
Unrelated things
The pipe |>
operator and the Boolean-OR operator ||
are not the same as using the operator |
. F # allows operators to be any combination of characters, and they can have very different meanings from an operator that looks much the same. For example, >=
is a standard operator that means more. And many F # programs will define a custom operator >>=
. But although >>=
not defined in the core F # library, it has a standard meaning, and the default is NOT "much more". Rather, it >>=
is the standard way of writing a statement for a function bind
. I will not go into what it is bind
doing right now, as a concept that could fully answer all the questions. But if you are wondering howbind
, you can read Scott Ulashin's version of Computation Expressions which explains it very well.
source to share