import Data.Maybe cao_20_7_4 = (*1.15) kg_to_lb = (*2.2) ft_to_metre = (*0.3048) litre_to_kg_avgas = (*0.72) taxi_fuel_kg = 5 modrem x d = fromInteger (x `mod` d) / fromInteger d -- Calculate pressure altitude isatemp = 15 isapressure = 1013.25 pressure_altitude ele qnh = max 0 (fromIntegral ele + (isapressure - fromIntegral qnh) * 30) declared_temp da = isatemp - da / 500 -- Find the 4 numbers to interpolate -- nw ne -- sw se -- Calculate the proportion of the temperature to interpolate (0 >= temp_prop <= 1) -- Calculate the proportion of the pressure altutide to interpolate (0 >= pa_prop <= 1) data DistanceRequired = DistanceRequired { distance_required_ft :: Double , distance_required_ft_cao20_7_4 :: Double , distance_required_metre :: Double , distance_required_metre_cao20_7_4 :: Double } deriving (Eq, Show) f <<$>> DistanceRequired nw sw ne se = DistanceRequired (f nw) (f sw) (f ne) (f se) eachDistanceRequired f (DistanceRequired nw1 sw1 ne1 se1) (DistanceRequired nw2 sw2 ne2 se2) = DistanceRequired (f nw1 nw2) (f sw1 sw2) (f ne1 ne2) (f se1 se2) distanceRequired1 x = DistanceRequired x (cao_20_7_4 x) (ft_to_metre x) (cao_20_7_4 (ft_to_metre x)) grass gr clear50ft = let gr' = (*1.45) <<$>> gr t = eachDistanceRequired (+) (eachDistanceRequired (-) clear50ft gr) gr' in (gr', t) interpolate :: Double -> Double -> Double -> Double -> Double -> Double -> DistanceRequired interpolate nw sw ne se da temp = let temp_prop = modrem (round temp) 10 interpolate' a b prop = (a-b)*prop+b interpolate_temp a b = interpolate' a b temp_prop result = interpolate' (interpolate_temp se sw) (interpolate_temp ne nw) (modrem (round da) 1000) in distanceRequired1 result data Check a = Check a a deriving (Eq, Ord, Show) (===) :: a -> a -> Check a (===) = Check infixl 4 === v :: Check a -> a v (Check a _) = a check :: (Show a, Eq a) => Check a -> Maybe String check (Check a1 a2) = if a1 == a2 then Nothing else Just (concat [show a1, " /= ", show a2]) ---- ---- YBAF ybaf_declared_density = 2400 -- ft ybaf_ele = 65 -- ft ybaf_declared_density_height = ybaf_declared_density + ybaf_ele === 2465 ybaf_declared_temp = declared_temp (v ybaf_declared_density_height) === 10.07 ybaf_interpolate nw sw ne se = interpolate nw sw ne se (v ybaf_declared_density_height) (v ybaf_declared_temp) ---- YRED yred_declared_density = 2400 -- ft yred_ele = 7 -- ft yred_declared_density_height = yred_declared_density + yred_ele === 2407 yred_declared_temp = declared_temp (v yred_declared_density_height) === 10.186 yred_interpolate nw sw ne se = interpolate nw sw ne se (v yred_declared_density_height) (v yred_declared_temp) ---- YBSU ybsu_declared_density = 2400 -- ft ybsu_ele = 15 -- ft ybsu_declared_density_height = ybsu_declared_density + ybsu_ele === 2415 ybsu_declared_temp = declared_temp (v ybsu_declared_density_height) === 10.17 ybsu_interpolate nw sw ne se = interpolate nw sw ne se (v ybsu_declared_density_height) (v ybsu_declared_temp) ---- YTWB ytwb_declared_density = 2500 -- ft ytwb_ele = 2086 -- ft ytwb_declared_density_height = ytwb_declared_density + ytwb_ele === 4586 ytwb_declared_temp = declared_temp (v ytwb_declared_density_height) === 5.827999999999999 ytwb_interpolate nw sw ne se = interpolate nw sw ne se (v ytwb_declared_density_height) (v ytwb_declared_temp) ---- -- TODR YBAF -- *2400lb* todr_ybaf_groundroll = ybaf_interpolate 1035 1140 2060 2295 === DistanceRequired { distance_required_ft = 1083.825 , distance_required_ft_cao20_7_4 = 1246.39875 , distance_required_metre = 330.34986000000004 , distance_required_metre_cao20_7_4 = 379.902339 } todr_ybaf_50ft = ybaf_interpolate 1910 2120 2060 2295 === DistanceRequired { distance_required_ft = 2007.65 , distance_required_ft_cao20_7_4 = 2308.7975 , distance_required_metre = 611.93172 , distance_required_metre_cao20_7_4 = 703.721478 } -- LDR YRED -- *2400lb* ldr_yred_groundroll = yred_interpolate 570 590 590 615 === DistanceRequired { distance_required_ft = 578.14 , distance_required_ft_cao20_7_4 = 664.8609999999999 , distance_required_metre = 176.217072 , distance_required_metre_cao20_7_4 = 202.64963279999998 } ldr_yred_50ft = ybsu_interpolate 1330 1360 1360 1395 === DistanceRequired { distance_required_ft = 1342.45 , distance_required_ft_cao20_7_4 = 1543.8174999999999 , distance_required_metre = 409.17876 , distance_required_metre_cao20_7_4 = 470.555574 } -- TODR YRED -- *2400lb* todr_yred_groundroll = yred_interpolate 1035 1140 2060 2295 === DistanceRequired { distance_required_ft = 1077.735 , distance_required_ft_cao20_7_4 = 1239.3952499999998 , distance_required_metre = 328.493628 , distance_required_metre_cao20_7_4 = 377.7676722 } todr_yred_50ft = yred_interpolate 1910 2120 2060 2295 === DistanceRequired { distance_required_ft = 1995.47 , distance_required_ft_cao20_7_4 = 2294.7905 , distance_required_metre = 608.2192560000001 , distance_required_metre_cao20_7_4 = 699.4521444000001 } -- LDR YBSU -- *2400lb* ldr_ybsu_groundroll = ybsu_interpolate 570 590 590 615 === DistanceRequired { distance_required_ft = 578.3 , distance_required_ft_cao20_7_4 = 665.0449999999998 , distance_required_metre = 176.26584 , distance_required_metre_cao20_7_4 = 202.70571599999997 } ldr_ybsu_50ft = ybsu_interpolate 1330 1360 1360 1395 === DistanceRequired { distance_required_ft = 1342.45 , distance_required_ft_cao20_7_4 = 1543.8174999999999 , distance_required_metre = 409.17876 , distance_required_metre_cao20_7_4 = 470.555574 } -- TODR YBSU -- *2400lb* todr_ybsu_groundroll = ybsu_interpolate 1035 1140 2060 2295 === DistanceRequired { distance_required_ft = 1078.575 , distance_required_ft_cao20_7_4 = 1240.36125 , distance_required_metre = 328.74966 , distance_required_metre_cao20_7_4 = 378.06210899999996 } todr_ybsu_50ft = ybsu_interpolate 1910 2120 2060 2295 === DistanceRequired { distance_required_ft = 1997.15 , distance_required_ft_cao20_7_4 = 2296.7225 , distance_required_metre = 608.7313200000001 , distance_required_metre_cao20_7_4 = 700.041018 } -- LDR YTWB -- *2400lb* ldr_ytwb_groundroll = ytwb_interpolate 595 615 615 640 === DistanceRequired { distance_required_ft = 620.478 , distance_required_ft_cao20_7_4 = 713.5496999999999 , distance_required_metre = 189.1216944 , distance_required_metre_cao20_7_4 = 217.48994856 } ldr_ytwb_50ft = ytwb_interpolate 1365 1400 1400 1435 === DistanceRequired { distance_required_ft = 1406.51 , distance_required_ft_cao20_7_4 = 1617.4865 , distance_required_metre = 428.704248 , distance_required_metre_cao20_7_4 = 493.0098852 } -- TODR YTWB -- *2400lb* todr_ytwb_groundroll = ytwb_interpolate 1165 1285 1260 1390 === DistanceRequired { distance_required_ft = 1295.836 , distance_required_ft_cao20_7_4 = 1490.2114 , distance_required_metre = 394.97081280000003 , distance_required_metre_cao20_7_4 = 454.21643472 } todr_ytwb_50ft = ytwb_interpolate 2165 2445 2365 2660 === DistanceRequired { distance_required_ft = 2454.354 , distance_required_ft_cao20_7_4 = 2822.5070999999994 , distance_required_metre = 748.0870992 , distance_required_metre_cao20_7_4 = 860.30016408 } -- LDR YBAF -- *2400lb* ldr_ybaf_groundroll = ybaf_interpolate 550 570 570 590 === DistanceRequired { distance_required_ft = 559.3 , distance_required_ft_cao20_7_4 = 643.1949999999999 , distance_required_metre = 170.47464 , distance_required_metre_cao20_7_4 = 196.04583599999998 } ldr_ybaf_50ft = ybaf_interpolate 1295 1330 1330 1360 === DistanceRequired { distance_required_ft = 1311.275 , distance_required_ft_cao20_7_4 = 1507.96625 , distance_required_metre = 399.67662000000007 , distance_required_metre_cao20_7_4 = 459.62811300000004 } ---- ybaf_checks = [ ybaf_declared_density_height , ybaf_declared_temp ] ybsu_checks = [ ybsu_declared_density_height , ybsu_declared_temp ] ytwb_checks = [ ytwb_declared_density_height , ytwb_declared_temp ] todr_ybaf_checks = [ todr_ybaf_groundroll , todr_ybaf_50ft ] ldr_yred_checks = [ ldr_yred_groundroll , ldr_yred_50ft ] todr_yred_checks = [ todr_yred_groundroll , todr_yred_50ft ] yred_checks = concat [ [ yred_declared_density_height , yred_declared_temp ] ] ldr_ybsu_checks = [ ldr_ybsu_groundroll , ldr_ybsu_50ft ] todr_ybsu_checks = [ todr_ybsu_groundroll , todr_ybsu_50ft ] ldr_ytwb_checks = [ ldr_ytwb_groundroll , ldr_ytwb_50ft ] todr_ytwb_checks = [ todr_ytwb_groundroll , todr_ytwb_50ft ] ldr_ybaf_checks = [ ldr_ybaf_groundroll , ldr_ybaf_50ft ] checks = concat [ ybaf_checks , yred_checks , ybsu_checks , ytwb_checks ] todr_checks = concat [ todr_ybaf_checks , todr_yred_checks , todr_ybsu_checks , todr_ytwb_checks ] ldr_checks = concat [ ldr_ybsu_checks , ldr_yred_checks , ldr_ytwb_checks , ldr_ybaf_checks ] all_checks = map check checks ++ map check todr_checks ++ map check ldr_checks failed_checks = catMaybes all_checks