It’s not necessary! But, it is really handy.
In practice, <|
means you don’t need to use parentheses. So these things are equivalent:
Dict.get "a" (Dict.fromList [("a", 1), ("b", 2)])
Dict.get "a" <| Dict.fromList [("a", 1), ("b", 2)]
The first example ends with )])
, which can be confusing! And as expressions get more complex, it gets even worse. When you get to the level of a unit test, you get something like this:
test "getting an item from a dictionary"
(\_ ->
Expect.equal 1 (Dict.get "a" (Dict.fromList [("a", 1)]))
)
Now we’re up to )]))
! You may be better at this than I am, but the chances I’ll be able to modify this syntax correctly are quite low. Let’s refactor using <|
:
test "getting an item from a dictionary" <|
\_ ->
Expect.equal 1 (Dict.get "a" (Dict.fromList [("a", 1)]))
Better already! What if we put another one to remove the parentheses around Dict.get
?
test "getting an item from a dictionary" <|
\_ ->
Expect.equal 1 <| Dict.get "a" (Dict.fromList [("a", 1)])
And, another for the Dict.fromList
?
test "getting an item from a dictionary" <|
\_ ->
Expect.equal 1 <| Dict.get "a" <| Dict.fromList [("a", 1)]
Nice! No parentheses. But, this is still pretty confusing. You have to read it backwards! So, let’s change this to use |>
, which does the same thing as <|
but with the arguments flipped:
test "getting an item from a dictionary" <|
\_ ->
Dict.fromList [("a", 1)]
|> Dict.get "a"
|> Expect.equal 1
Much better! In fact, the functions in Expect
were designed with |>
in mind. That’s why the expected values are consistently the first arguments, instead of the last ones.
Finally, there are some rules I like to use about <|
so that things stay nice and clear:
- Don’t ever use
<|
more than once in an expression.
- Don’t ever mix
<|
and |>
in the same expression (the test above is two separate expressions.)
- Don’t use
<|
in simple cases. add <| 1 <| 1
and add 1 1
both result in 2
, but one is significantly clearer.
Oh, and a last tidbit: I’ve heard these called many things, but my favorite are “left pizza” and “right pizza”
Edit: I keep thinking of things! If you’re trying to find examples of this in other languages, <|
is sometimes written $
. So add $ 1 $ 1
. IMO <|
is nicer to use since it implies direction once you know what |>
does.
I’ve also written about this previously, if you want more examples.