module Data.Geo.Jord.Speed
(
Speed
, average
, metresPerSecond
, kilometresPerHour
, milesPerHour
, knots
, feetPerSecond
, speed
, read
, toMetresPerSecond
, toKilometresPerHour
, toMilesPerHour
, toKnots
, toFeetPerSecond
, add
, subtract
, zero
) where
import Control.Applicative ((<|>))
import Prelude hiding (read, subtract)
import Text.ParserCombinators.ReadP (ReadP, pfail, readP_to_S, skipSpaces, string)
import Text.Read (readMaybe)
import Data.Geo.Jord.Duration (Duration)
import qualified Data.Geo.Jord.Duration as Duration (toHours)
import Data.Geo.Jord.Length (Length)
import qualified Data.Geo.Jord.Length as Length (toMillimetres)
import Data.Geo.Jord.Parser
newtype Speed =
Speed
{ Speed -> Int
mmPerHour :: Int
}
deriving (Speed -> Speed -> Bool
(Speed -> Speed -> Bool) -> (Speed -> Speed -> Bool) -> Eq Speed
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Speed -> Speed -> Bool
$c/= :: Speed -> Speed -> Bool
== :: Speed -> Speed -> Bool
$c== :: Speed -> Speed -> Bool
Eq)
instance Read Speed where
readsPrec :: Int -> ReadS Speed
readsPrec Int
_ = ReadP Speed -> ReadS Speed
forall a. ReadP a -> ReadS a
readP_to_S ReadP Speed
speed
instance Show Speed where
show :: Speed -> String
show Speed
s = Double -> String
forall a. Show a => a -> String
show (Speed -> Double
toKilometresPerHour Speed
s) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"km/h"
instance Ord Speed where
<= :: Speed -> Speed -> Bool
(<=) (Speed Int
s1) (Speed Int
s2) = Int
s1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
s2
add :: Speed -> Speed -> Speed
add :: Speed -> Speed -> Speed
add Speed
a Speed
b = Int -> Speed
Speed (Speed -> Int
mmPerHour Speed
a Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Speed -> Int
mmPerHour Speed
b)
subtract :: Speed -> Speed -> Speed
subtract :: Speed -> Speed -> Speed
subtract Speed
a Speed
b = Int -> Speed
Speed (Speed -> Int
mmPerHour Speed
a Int -> Int -> Int
forall a. Num a => a -> a -> a
- Speed -> Int
mmPerHour Speed
b)
zero :: Speed
zero :: Speed
zero = Int -> Speed
Speed Int
0
average :: Length -> Duration -> Speed
average :: Length -> Duration -> Speed
average Length
d Duration
t = Int -> Speed
Speed (Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
round (Double
mm Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
h))
where
mm :: Double
mm = Length -> Double
Length.toMillimetres Length
d
h :: Double
h = Duration -> Double
Duration.toHours Duration
t
metresPerSecond :: Double -> Speed
metresPerSecond :: Double -> Speed
metresPerSecond Double
mps = Int -> Speed
Speed (Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
round (Double
mps Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
3600000.0))
kilometresPerHour :: Double -> Speed
kilometresPerHour :: Double -> Speed
kilometresPerHour Double
kph = Int -> Speed
Speed (Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
round (Double
kph Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
1e+6))
milesPerHour :: Double -> Speed
milesPerHour :: Double -> Speed
milesPerHour Double
mph = Int -> Speed
Speed (Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
round (Double
mph Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
1609344.0))
knots :: Double -> Speed
knots :: Double -> Speed
knots Double
kt = Int -> Speed
Speed (Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
round (Double
kt Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
1852000.0))
feetPerSecond :: Double -> Speed
feetPerSecond :: Double -> Speed
feetPerSecond Double
fps = Int -> Speed
Speed (Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
round (Double
fps Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
1097280.0))
read :: String -> Maybe Speed
read :: String -> Maybe Speed
read String
s = String -> Maybe Speed
forall a. Read a => String -> Maybe a
readMaybe String
s :: (Maybe Speed)
toMetresPerSecond :: Speed -> Double
toMetresPerSecond :: Speed -> Double
toMetresPerSecond (Speed Int
s) = Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
3600000.0
toKilometresPerHour :: Speed -> Double
toKilometresPerHour :: Speed -> Double
toKilometresPerHour (Speed Int
s) = Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
1e+6
toMilesPerHour :: Speed -> Double
toMilesPerHour :: Speed -> Double
toMilesPerHour (Speed Int
s) = Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
1609344.0
toKnots :: Speed -> Double
toKnots :: Speed -> Double
toKnots (Speed Int
s) = Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
1852000.0
toFeetPerSecond :: Speed -> Double
toFeetPerSecond :: Speed -> Double
toFeetPerSecond (Speed Int
s) = Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
1097280.0
speed :: ReadP Speed
speed :: ReadP Speed
speed = do
Double
s <- ReadP Double
number
ReadP ()
skipSpaces
String
u <- String -> ReadP String
string String
"m/s" ReadP String -> ReadP String -> ReadP String
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> String -> ReadP String
string String
"km/h" ReadP String -> ReadP String -> ReadP String
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> String -> ReadP String
string String
"mph" ReadP String -> ReadP String -> ReadP String
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> String -> ReadP String
string String
"kt" ReadP String -> ReadP String -> ReadP String
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> String -> ReadP String
string String
"ft/s"
case String
u of
String
"m/s" -> Speed -> ReadP Speed
forall (m :: * -> *) a. Monad m => a -> m a
return (Double -> Speed
metresPerSecond Double
s)
String
"km/h" -> Speed -> ReadP Speed
forall (m :: * -> *) a. Monad m => a -> m a
return (Double -> Speed
kilometresPerHour Double
s)
String
"mph" -> Speed -> ReadP Speed
forall (m :: * -> *) a. Monad m => a -> m a
return (Double -> Speed
milesPerHour Double
s)
String
"kt" -> Speed -> ReadP Speed
forall (m :: * -> *) a. Monad m => a -> m a
return (Double -> Speed
knots Double
s)
String
"ft/s" -> Speed -> ReadP Speed
forall (m :: * -> *) a. Monad m => a -> m a
return (Double -> Speed
feetPerSecond Double
s)
String
_ -> ReadP Speed
forall a. ReadP a
pfail