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

Tools:

### measures and type declerations

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

### calculation with haversine-formula

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

`1: let GreatCircleDistanceOnEarth = GreatCircleDistance 6371.0<km>`

### example

```1: let p1 = { Latitude = 53.147222222222222222222222222222<deg>; Longitude = 0.96666666666666666666666666666667<deg> }
2:
3: let p2 = { Latitude = 52.204444444444444444444444444444<deg>; Longitude = 0.14055555555555555555555555555556<deg> }
4:
5: GreatCircleDistanceOnEarth p1 p2```
Multiple items
module Measure

from Microsoft.FSharp.Math

--------------------

type MeasureAttribute =
class
inherit System.Attribute
new : unit -> MeasureAttribute
end

Full name: Microsoft.FSharp.Core.MeasureAttribute

type: MeasureAttribute
implements: System.Runtime.InteropServices._Attribute
inherits: System.Attribute
[<Measure>]

[<Measure>]
type deg

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

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

Full name: Snippet.Location

type: Location
implements: System.IEquatable<Location>
implements: System.Collections.IStructuralEquatable
implements: System.IComparable<Location>
implements: System.IComparable
implements: System.Collections.IStructuralComparable
Location.Latitude: float<deg>
Multiple items
val float : 'T -> float (requires member op_Explicit)

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

--------------------

type float<'Measure> = float

Full name: Microsoft.FSharp.Core.float<_>

type: float<'Measure>
implements: System.IComparable
implements: System.IConvertible
implements: System.IFormattable
implements: System.IComparable<float<'Measure>>
implements: System.IEquatable<float<'Measure>>
inherits: System.ValueType

--------------------

type float = System.Double

Full name: Microsoft.FSharp.Core.float

type: float
implements: System.IComparable
implements: System.IFormattable
implements: System.IConvertible
implements: System.IComparable<float>
implements: System.IEquatable<float>
inherits: System.ValueType
Location.Longitude: float<deg>
val GreatCircleDistance : float<'u> -> Location -> Location -> float<'u>

Full name: Snippet.GreatCircleDistance
Multiple items
val R : float<'u>

type: float<'u>
implements: System.IComparable
implements: System.IConvertible
implements: System.IFormattable
implements: System.IComparable<float<'u>>
implements: System.IEquatable<float<'u>>
inherits: System.ValueType

--------------------

val R : float<'u>

type: float<'u>
implements: System.IComparable
implements: System.IConvertible
implements: System.IFormattable
implements: System.IComparable<float<'u>>
implements: System.IEquatable<float<'u>>
inherits: System.ValueType
val p1 : Location

type: Location
implements: System.IEquatable<Location>
implements: System.Collections.IStructuralEquatable
implements: System.IComparable<Location>
implements: System.IComparable
implements: System.Collections.IStructuralComparable
val p2 : Location

type: Location
implements: System.IEquatable<Location>
implements: System.Collections.IStructuralEquatable
implements: System.IComparable<Location>
implements: System.IComparable
implements: System.Collections.IStructuralComparable
val x : float<deg>

type: float<deg>
implements: System.IComparable
implements: System.IConvertible
implements: System.IFormattable
implements: System.IComparable<float<deg>>
implements: System.IEquatable<float<deg>>
inherits: System.ValueType
namespace System
type Math =
class
static val PI : float
static val E : float
static member Abs : System.SByte -> System.SByte
static member Abs : int16 -> int16
static member Abs : int -> int
static member Abs : int64 -> int64
static member Abs : float32 -> float32
static member Abs : float -> float
static member Abs : decimal -> decimal
static member Acos : float -> float
static member Asin : float -> float
static member Atan : float -> float
static member Atan2 : float * float -> float
static member BigMul : int * int -> int64
static member Ceiling : decimal -> decimal
static member Ceiling : float -> float
static member Cos : float -> float
static member Cosh : float -> float
static member DivRem : int * int * int -> int
static member DivRem : int64 * int64 * int64 -> int64
static member Exp : float -> float
static member Floor : decimal -> decimal
static member Floor : float -> float
static member IEEERemainder : float * float -> float
static member Log : float -> float
static member Log : float * float -> float
static member Log10 : float -> float
static member Max : System.SByte * System.SByte -> System.SByte
static member Max : System.Byte * System.Byte -> System.Byte
static member Max : int16 * int16 -> int16
static member Max : uint16 * uint16 -> uint16
static member Max : int * int -> int
static member Max : uint32 * uint32 -> uint32
static member Max : int64 * int64 -> int64
static member Max : uint64 * uint64 -> uint64
static member Max : float32 * float32 -> float32
static member Max : float * float -> float
static member Max : decimal * decimal -> decimal
static member Min : System.SByte * System.SByte -> System.SByte
static member Min : System.Byte * System.Byte -> System.Byte
static member Min : int16 * int16 -> int16
static member Min : uint16 * uint16 -> uint16
static member Min : int * int -> int
static member Min : uint32 * uint32 -> uint32
static member Min : int64 * int64 -> int64
static member Min : uint64 * uint64 -> uint64
static member Min : float32 * float32 -> float32
static member Min : float * float -> float
static member Min : decimal * decimal -> decimal
static member Pow : float * float -> float
static member Round : float -> float
static member Round : decimal -> decimal
static member Round : float * int -> float
static member Round : float * System.MidpointRounding -> float
static member Round : decimal * int -> decimal
static member Round : decimal * System.MidpointRounding -> decimal
static member Round : float * int * System.MidpointRounding -> float
static member Round : decimal * int * System.MidpointRounding -> decimal
static member Sign : System.SByte -> int
static member Sign : int16 -> int
static member Sign : int -> int
static member Sign : int64 -> int
static member Sign : float32 -> int
static member Sign : float -> int
static member Sign : decimal -> int
static member Sin : float -> float
static member Sinh : float -> float
static member Sqrt : float -> float
static member Tan : float -> float
static member Tanh : float -> float
static member Truncate : decimal -> decimal
static member Truncate : float -> float
end

Full name: System.Math
field System.Math.PI = 3.14159265359
val sq : (float -> float)
val x : float

type: float
implements: System.IComparable
implements: System.IFormattable
implements: System.IConvertible
implements: System.IComparable<float>
implements: System.IEquatable<float>
inherits: System.ValueType
val sinSqHf : (float<rad> -> float)

implements: System.IComparable
implements: System.IConvertible
implements: System.IFormattable
inherits: System.ValueType
System.Math.Sin(a: float) : float
val cos : (float<deg> -> float)
val a : float<deg>

type: float<deg>
implements: System.IComparable
implements: System.IConvertible
implements: System.IFormattable
implements: System.IComparable<float<deg>>
implements: System.IEquatable<float<deg>>
inherits: System.ValueType
System.Math.Cos(d: float) : float

implements: System.IComparable
implements: System.IConvertible
implements: System.IFormattable
inherits: System.ValueType

implements: System.IComparable
implements: System.IConvertible
implements: System.IFormattable
inherits: System.ValueType
val a : float

type: float
implements: System.IComparable
implements: System.IFormattable
implements: System.IConvertible
implements: System.IComparable<float>
implements: System.IEquatable<float>
inherits: System.ValueType
val c : float

type: float
implements: System.IComparable
implements: System.IFormattable
implements: System.IConvertible
implements: System.IComparable<float>
implements: System.IEquatable<float>
inherits: System.ValueType
System.Math.Atan2(y: float, x: float) : float
System.Math.Sqrt(d: float) : float
val R : float<'u>

type: float<'u>
implements: System.IComparable
implements: System.IConvertible
implements: System.IFormattable
implements: System.IComparable<float<'u>>
implements: System.IEquatable<float<'u>>
inherits: System.ValueType
val GreatCircleDistanceOnEarth : (Location -> Location -> float<km>)

Full name: Snippet.GreatCircleDistanceOnEarth
val p1 : Location

Full name: Snippet.p1

type: Location
implements: System.IEquatable<Location>
implements: System.Collections.IStructuralEquatable
implements: System.IComparable<Location>
implements: System.IComparable
implements: System.Collections.IStructuralComparable
val p2 : Location

Full name: Snippet.p2

type: Location
implements: System.IEquatable<Location>
implements: System.Collections.IStructuralEquatable
implements: System.IComparable<Location>
implements: System.IComparable
implements: System.Collections.IStructuralComparable