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

Comments

# 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 :)

# re: Distance between adjacent points in F#

Saturday, March 21, 2009 7:02 AM by Faisal

Well sir, I am new in F# need little help from you.

I have installed Visual Studio 2008, then from Microsoft side I have installed the F# packages. They work fine for the consoule programming but when i try to make some windows application for each line it send me error.

Can you please do let me know how to solve this problem cause I really need it for my PhD work. How can I make windows application just like we do in C# and in VB.NET.

Regards

Faisal

sfaisalaliutp@gmail.com

# re: Distance between adjacent points in F#

Tuesday, November 08, 2011 8:57 PM by KateCamson

Good post  at least I thing so. Keep it up!

Kate Camson

<a href="bratislava-escort.com/">escorts a bratislava</a>

Leave a Comment

(required) 
(required) 
(optional)
(required)