As others mentioned, pipelining is more like a UNIX shell pipeline. It let's you write some input followed by operations that should be applied to it, instead of usual nested function calls. In this example, the standard F# code would look like this:
let r = List.map (add 10) (List.filter (fun n-> n%2 <> 0) nums)
Note that the input nums
is deeply nested in the expression and it isn't easy to see that it is first filtered and then projected. Using pipelining, you can write the code differently, but it will mean exactly the same thing.
The trick is that pipelining operator takes two parameters using infix notation (e.g. x |> f
). The x
parameter will be passed as the last argument to a function on the right (f
). You can use pipelining with any F# functions:
let sinOne = 1.0 |> sin
let add a b = a + b
let r = 10 |> add 5 // it doesn't always make code more readable :-)
An important point about F# pipelining operator is that it isn't any special built-in feature of the language. It is a simple custom operator that you can define on your own:
let (|>) x f = f x
// Thanks to operator associativity rules, the following:
let r = 1.0 |> sin |> sqrt
// ...means this:
let r = (1.0 |> sin) |> sqrt