F# – Pipe Forward and Pipe Backward

I’m taking a bit of time to brush up my knowledge of F# and see if I can write better F# code and one of the things I notice is that whilst I use pipe-forward operator (|>) often when working with collections I don’t nearly use the pipe-backward operator (<|) as frequently as I should. It makes sense as the pipe-forward operator works similar to the way LINQ and IEnumerable works, just to remind myself and others like me how these work:

Pipe-forward operator (|>)

Pipe-forward operator lets you pass an intermediate result onto the next function, it’s defined as:

let (|>) x f = f x

For instance, to apply a filter (i.e. IEnumerable.Where) for even numbers to a list of integers from 1 to 10, you can write:

image

You can add further processing steps to this intermediate result:

image

Forward composition operator (>>)

The forward composition operator lets you ‘compose’ functions together in a way similar to the way the pipe-forward operator lets you chain function delegates together, it is defined as:

let (>>) f g x = g (f x)

Now imagine if you have two functions:

image

You can use them to build a high-order function that returns triples the square of a float, n, using the >> operator:

image

This is syntactically cleaner and easier to read than:

image

and it’s especially useful when chaining together a large number of functions.

Pipe-backward operator (<|)

The pipe-backward operator takes a function on the left and applies it to a value on the right:

let (<|) f x = f x

As unnecessary as it seems, the pipe-backward operator has an important purpose in allowing you to change operator precedence without those dreaded parentheses everywhere and improve readability of your code,.

For example:

image

can be written as

image

Backward composition operator (<<)

The inverse of the forward composition operator, the << operator takes two functions and applies the right function first and then the left, it’s defined as:

let (<<) f g x = f (g x)

Mostly I find it more suitable than the forward composition operator in cases where you want to negate the result of some function, for example, to find the odd numbers in a list:

image