F# tips weekly #3: piped lambda function
Usage of lambda functions as parameters for another function is well known. Less commonly used is the application of lambda functions in other contexts. We can leverage the fact that a lambda function is a value and use it wherever we can use a normal function. Let's explore the combination of lambda functions with the pipe |>
operator.
One great application is to call a function with a parameter other than the last, which can be quite common with Map
or Set
:
let updateWithDefault key def (m: Map<_, _>) =
m
|> Map.tryFind key
|> Option.defaultValue def
|> fun x -> Map.add key x m
When we have a value that we want to add to a Map, we can't use |> Map.add
directly. However, with a lambda function, we can pass the value from the pipe as any parameter.
fun x -> Map.add key x m
when used together with the |>
operator. This is because the |>
operator has lower precedence than function application.Another application is inlining single-case pattern matching as we seen in previous week:
createTriple
|> fun (a, b, c) -> a + b + c
Also, we can use an active pattern:
value
|> someCSharpMethod
|> function FromNull o -> o
|> Option.defaultValue ...
Here, we use the function
keyword, which is a shortcut for fun x -> match x with ...
. This can also be used, of course, to handle multiple cases:
maybeValue
|> function
| Some v -> v
| None -> defaultValue
Another related technique is to inline an if
condition in the pipe. We can use the id
function to do nothing and pass the value through:
[1..10]
|> if filterEnabled then List.filter (fun x -> x % 2 = 0) else id
A nice advantage of this technique is that List.filter
is not called for the else
case, in contrast to:
[1..10]
|> List.filter (fun x -> if filterEnabled then x % 2 = 0 else true)
Overall, I believe using lambda functions with the pipe is a useful tool that can make code more readable and concise, especially when there is no need to create a new binding. When using pipes, don't forget that the value in the pipe is only one |> fun x ->
away!
Subscribe to my newsletter
Read articles from Jindřich Ivánek directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Jindřich Ivánek
Jindřich Ivánek
Software developer focused mainly on F#, with a passion for functional programming, problem solving, efficient algorithms and programming languages. I have a strong computer science background, focused mainly in graph theory and graph algorithms; also was intrigued by data structures, complexity, and computability theory. Experienced with backend F# programming. I worked with mathematical optimization (mixed integer programming) and use of statistical methods as well. I contributed to several open source F# projects, mostly around developer tooling.