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))
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.