Skip to content

Instantly share code, notes, and snippets.

@ploeh
Last active December 2, 2022 14:11
Show Gist options
  • Save ploeh/6d8050e121a5175fabb1d08ef5266cd7 to your computer and use it in GitHub Desktop.
Save ploeh/6d8050e121a5175fabb1d08ef5266cd7 to your computer and use it in GitHub Desktop.
Helpful functions for working with pairs in F#
module Tuple2
let replicate x = x, x
let curry f x y = f (x, y)
let uncurry f (x, y) = f x y
let swap (x, y) = (y, x)
let mapFst f (x, y) = f x, y
let mapSnd f (x, y) = x, f y
let extendFst f (x,y) = f (x,y), y
let extendSnd f (x,y) = x, f(x,y)
let optionOfFst f (x, y) =
match f x with
| Some x' -> Some (x', y)
| None -> None
let optionOfSnd f (x, y) =
match f y with
| Some y' -> Some (x, y')
| None -> None
@ploeh
Copy link
Author

ploeh commented Sep 12, 2016

As an example, imagine that you want to count all the even and odd numbers in a list of numbers. You can use Tuple2.mapSnd to map the second element of a grouping tuple to count the number of occurrences in each group:

> numbers |> List.groupBy isEven;;
> val it : (bool * int list) list =
  [(true,
    [38; 24; 48; 52; 26; 70; 74; 84; 74; 84; 74; 18; 4; 74; 34; 66; 50; 20; 76;
     40; 44; 44; 64; 46; 64; 50; 74; 96; 90; 92; 48; 8; 88; 96; 18; 86; 54; 40;
     58; 14; 84; 64; 86]);
   (false,
    [35; 55; 85; 61; 13; 99; 65; 35; 63; 13; 9; 9; 13; 91; 57; 87; 31; 1; 63;
     23; 63; 3; 11; 57; 85; 87; 39; 51; 47; 47; 17; 63; 67; 65; 55; 43; 13; 71;
     99; 11; 97; 59; 65; 55; 15; 35; 43; 67; 29; 87; 47; 3; 35; 37; 15; 73; 91])]
> numbers |> List.groupBy isEven |> List.map (Tuple2.mapSnd List.length);;
>
val it : (bool * int) list = [(true, 43); (false, 57)]

In this particular example, you could most likely come up with a simple and more efficient implementation, but I find the functions in the Tuple2 module handy for ad-hoc composition.

@ImaginaryDevelopment
Copy link

Can you add an example of where the extend functions are really useful? The rest I've already got lots of places I can think of where I would have used them.

@ploeh
Copy link
Author

ploeh commented Sep 17, 2016

I got the extend functions from Jérémie Chassaing: https://twitter.com/thinkb4coding/status/775427149243224064

@brianberns
Copy link

This one is also useful if a and b are of the same type:

let map f (a, b) = f a, f b

@ImaginaryDevelopment
Copy link

I typically call that one mapBoth @brianberns

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment