Create a gist now

Instantly share code, notes, and snippets.

@ploeh /Tuple2.fs
Last active Sep 17, 2016

What would you like to do?
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
Owner

ploeh commented Sep 9, 2016

In F#, it's convenient to compose functions together. The output of one function becomes the input of the next function. Often, the type of the data flowing from one to the next function is a tuple, and most of the time, it's a pair (a tuple with two elements).

Sometimes, you need to translate a pair from one form into another. The Tuple2 module contains a small set of functions I often find useful when working with pairs.

Owner

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.

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.

Owner

ploeh commented Sep 17, 2016

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

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