## Distance between adjacent points in F#

Let’s say you are given a list of data points:

[7;5;12;8;5]

And you are asked to find the distance between every adjacent pair, that is:

[(7-5);(5-12);(12-8);(8-5)] = [2;-7;4;3]

It turns out that there is an elegant solution to this problem:

let rec pairs = function
| h1 :: (h2 :: _ as tail) -> (h1, h2) :: pairs tail
| _ –> []

let distances dataPoints =
dataPoints |> pairs |> List.map (fun (a, b) -> a - b)

The magic happens in the pairs function, this function takes [7;5;12;8;5] and turns it into [(7,5);(5,12);(12,8);(8,5)], that is, it creates a tuple with every member of the list and its right neighbor. The trick is that tail gets bounded  to ( h2 :: _ ), so that the recursive call processes the list starting with h2. This is called a named subpattern, something I discovered in section 1.4.2.2 of F# for Scientists. You learn at least a nice thing every day!

Published Thursday, March 12, 2009 11:57 PM by Edgar Sánchez

#### # re: Distance between adjacent points in F#

Friday, March 13, 2009 7:56 AM by CKoenig

You can have this even shorter:

let distances pts = pts |> Seq.pairwise |> Seq.map (fun (a,b) -> a-b)

this yields a "seq<int> -> seq<int>" that works with your list in the expected way

#### # re: Distance between adjacent points in F#

Friday, March 13, 2009 9:23 AM by David Gates

In Scala, I'd make a list of adjacent pairs like this:

list.init.zip(list.tail)

I assume this can be translated to F#.

#### # re: Distance between adjacent points in F#

Friday, March 13, 2009 10:07 AM by David Gates

Correction: the init is unnecessary, since zip ignores any extra elements.

list.zip(list.tail)

#### # re: Distance between adjacent points in F#

Friday, March 13, 2009 12:25 PM by Edgar Sánchez

@David

Unfortunately the zip function in F# requires that both lists have the same size, so we need a little helper:

let allButLast list = list |> List.rev |> List.tl |> List.rev

Not the most efficient implementation :-) but you get my point. And then the translation of your Scala code would be:

List.zip (allButLast list) list.Tail

But yes, in this case your code is shorter (and probably more elegant) than mine.

#### # re: Distance between adjacent points in F#

Friday, March 13, 2009 4:57 PM by Matt

Careful, your recursive pairs function isn't tail recurisve :)