This works because of operator precedence. The function application operator, juxtaposition or
(the space), has the highest precedence, so take 34 fibseq |> filter even
parses as ((take 34) fibseq) |> (filter even)
, which is equivalent to (filter even) ((take 34) fibseq)
; since function application is left-associative, this is then equivalent to filter even (take 34 fibseq)
.
In general, any binary operator can be given a precedence with a fixity declaration, such as
infixl 0 |>
infixr 9 .
The l
or r
says whether the operation is left- or right-associative (that is, whether a • b • c
groups as (a • b) • c
or a • (b • c)
); the number—an integer between 0 and 9—specifies the precedence level. Higher numbers mean higher precedence (with application having an effective precedence of ∞); for instance, *
and /
have precedence 7, and +
and -
have precedence 6. To check the precedence of an operator in ghci, just type :info $
(or whichever operator) at the prompt.
And just as a note: your code will work, but it's not how I would typically write it. If you're curious, in Haskell, I would write that code with the $
operator, which just performs function application but is low precedence: filter even $ take 34 fibseq
. If I had more functions to apply, I would use the composition operator: fun1 arg1 . fun2 . fun3 arg2 arg3 . filter even $ take 34 fibseq
. It reads the other way, but it's what you typically find in Haskell.