4 people like it.

# calculating the distance on earth (with units of measure)

calculating the distance between two locations on earth using haversine formula see http://en.wikipedia.org/wiki/Haversine_formula and implementing it using the posibilities of F#'s unit of measure system to avoid unit-conversion-errors concerning radians convertet the code found here: http://www.movable-type.co.uk/scripts/latlong.html for an concrete implementation

## measures and type declerations

 ```1: 2: 3: 4: ``` ``````[] type rad [] type deg [] type km type Location = { Latitude : float; Longitude : float } ``````

## calculation with haversine-formula

 ``` 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: ``` ``````let GreatCircleDistance<[] 'u> (R : float<'u>) (p1 : Location) (p2 : Location) = let degToRad (x : float) = System.Math.PI * x / 180.0 let sq x = x * x // take the sin of the half and square the result let sinSqHf (a : float) = (System.Math.Sin >> sq) (a / 2.0) let cos (a : float) = System.Math.Cos (degToRad a / 1.0) let dLat = (p2.Latitude - p1.Latitude) |> degToRad let dLon = (p2.Longitude - p1.Longitude) |> degToRad let a = sinSqHf dLat + cos p1.Latitude * cos p2.Latitude * sinSqHf dLon let c = 2.0 * System.Math.Atan2(System.Math.Sqrt(a), System.Math.Sqrt(1.0-a)) R * c ``````

## using the mean-earth-radius

 ```1: ``` ``````let GreatCircleDistanceOnEarth = GreatCircleDistance 6371.0 ``````

## example

 ```1: 2: 3: 4: 5: ``` ``````let p1 = { Latitude = 53.147222222222222222222222222222; Longitude = 0.96666666666666666666666666666667 } let p2 = { Latitude = 52.204444444444444444444444444444; Longitude = 0.14055555555555555555555555555556 } GreatCircleDistanceOnEarth p1 p2 ``````
Multiple items
type MeasureAttribute =
inherit Attribute
new : unit -> MeasureAttribute

Full name: Microsoft.FSharp.Core.MeasureAttribute

--------------------
new : unit -> MeasureAttribute
[<Measure>]

[<Measure>]
type deg

Full name: Script.deg
[<Measure>]
type km

Full name: Script.km
type Location =
{Latitude: float<deg>;
Longitude: float<deg>;}

Full name: Script.Location
Location.Latitude: float<deg>
Multiple items
val float : value:'T -> float (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.float

--------------------
type float = System.Double

Full name: Microsoft.FSharp.Core.float

--------------------
type float<'Measure> = float

Full name: Microsoft.FSharp.Core.float<_>
Location.Longitude: float<deg>
val GreatCircleDistance : R:float<'u> -> p1:Location -> p2:Location -> float<'u>

Full name: Script.GreatCircleDistance
val R : float<'u>
val p1 : Location
val p2 : Location
val x : float<deg>
namespace System
type Math =
static val PI : float
static val E : float
static member Abs : value:sbyte -> sbyte + 6 overloads
static member Acos : d:float -> float
static member Asin : d:float -> float
static member Atan : d:float -> float
static member Atan2 : y:float * x:float -> float
static member BigMul : a:int * b:int -> int64
static member Ceiling : d:decimal -> decimal + 1 overload
static member Cos : d:float -> float
...

Full name: System.Math
field System.Math.PI = 3.14159265359
val sq : (float -> float)
val x : float
val sinSqHf : (float<rad> -> float)
val a : float<rad>
System.Math.Sin(a: float) : float
val cos : (float<deg> -> float)
val a : float<deg>
System.Math.Cos(d: float) : float
val dLat : float<rad>
val dLon : float<rad>
val a : float
val c : float
System.Math.Atan2(y: float, x: float) : float
System.Math.Sqrt(d: float) : float
val GreatCircleDistanceOnEarth : (Location -> Location -> float<km>)

Full name: Script.GreatCircleDistanceOnEarth
val p1 : Location

Full name: Script.p1
val p2 : Location

Full name: Script.p2