Skip to content

Instantly share code, notes, and snippets.

@tjweir
Created January 2, 2019 00:59
Show Gist options
  • Save tjweir/167583602482b52054663e73a3db550b to your computer and use it in GitHub Desktop.
Save tjweir/167583602482b52054663e73a3db550b to your computer and use it in GitHub Desktop.
import Control.Applicative
import Text.ParserCombinators.ReadP
data WindInfo = WindInfo
{ dir :: Int
, speed :: Int
, gusts :: Maybe Int
}
deriving Show
data Report = Report
{ station :: String
, time :: (Int, Int, Int)
, wind :: WindInfo
}
deriving Show
metar :: ReadP Report
metar = do
code <- airport
time <- timestamp
wind <- windInfo
return (Report code time wind)ss
isVowel :: Char -> Bool
isVowel char =
any (char ==) "aouei"
vowel :: ReadP Char
vowel =
satisfy isVowel
atLeastOneVowel :: ReadP [Char]
atLeastOneVowel =
many1 vowel
airport :: ReadP String
airport = do
code <- many1 (satisfy (\char -> char >= 'A' && char <= 'Z'))
satisfy (== ' ')
return code
digit :: ReadP Char
digit =
satisfy (\char -> char >= '0' && char <= '9')
timestamp :: ReadP (Int, Int, Int)
timestamp = do
day <- numbers 2
hour <- numbers 2
minute <- numbers 2
string "Z "
if day < 1 || day > 31 || hour > 23 || minute > 59 then
pfail
else
return (day, hour, minute)
numbers :: Int -> ReadP Int
numbers digits =
fmap read (count digits digit)
gustParser :: ReadP Int
gustParser = do
satisfy (== 'G')
numbers 2 <|> numbers 3
windInfo :: ReadP WindInfo
windInfo = do
direction <- numbers 3
speed <- numbers 2 <|> numbers 3
gusts <- option Nothing (fmap Just gustParser)
unit <- string "KT" <|> string "MPS"
string " "
return (WindInfo
direction
(toMPS unit speed)
(fmap (toMPS unit) gusts))
toMPS :: String -> Int -> Int
toMPS unit speed =
case unit of
"KT" -> div speed 2
"MPS" -> speed
-- ghci> readP_to_S metar "BIRK 281500Z 09014G17KT CAVOK M03/M06 Q0980 R13/910195"
-- [(Report {station = "BIRK", time = (28,15,0), wind = WindInfo {dir = 90, speed = 7, gusts = Just 8}},"CAVOK M03/M06 Q0980 R13/910195")]
-- it :: [(Report, String)]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment