haskellmathdistancehaversine

Haskell - Incorrect distance returning from Haversine


I have the code below for calculating the Haversine distance between a list of airports, however it is consistently returning the incorrect value. For example, running the code below on ORD (Chicago) and JFK (NYC) by running haversine (head $ allAirports) (last $ allAirports) returns only 92.16479615931107 when the actual distance between ORD and JFK is approximately 827 miles. Any idea what I'm doing wrong in the calculation?

type Location = (Double, Double)

data Airport = Airport {
  name :: String,
  location :: Location
} deriving (Eq)

allAirports :: [Airport]
allAirports = [
   Airport { name="ORD", location=(41.9786,-87.9048)},
   Airport { name="JFK", location=(40.64505923593942, -73.777106518636)}]

 haversine :: Airport -> Airport -> Double
 haversine (Airport _ (x1,y1)) (Airport _ (x2,y2)) = radius * c
  where radius = 3959.87433
    to_rad :: Double -> Double
    to_rad x = (x * pi) / 180
    r_x1 = to_rad x1
    r_x2 = to_rad x2
    r_y1 = to_rad y1
    r_y2 = to_rad y1
    dlat = r_x2 - r_x1
    dlon = r_y2 - r_y1
    a = sin(dlat/2)**2 + cos(r_x1)*cos(r_x2)*sin(dlon/2)**2
    c = 2 * asin(sqrt(a)) 

Solution

  • You have a typo in here:

    r_y2 = to_rad y1
    

    ā€” should be y2 instead of y1. If you fix it, you get ~738 which is the correct answer. Your desired number, 827, seems to be what Google Maps shows for a driving distance, accounting for roads, etc. If you google "flight distance between jfk and ord", you get 738.