Skip to content

Instantly share code, notes, and snippets.

@Akii
Created October 13, 2019 08:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Akii/6f348f6987bf2d3f7ae1aa11edfd0b5c to your computer and use it in GitHub Desktop.
Save Akii/6f348f6987bf2d3f7ae1aa11edfd0b5c to your computer and use it in GitHub Desktop.
Parsing in Haskell is awesome
-- The goal was to parse a text describing the connection which is used by screen readers:
-- Strecke von Karlsruhe Hbf, Abfahrtszeit 11:59 von Gleis 3 nach Berlin Hauptbahnhof, Ankunftszeit 18:03 auf Gleis 2, mit ICE 370
-- Translated:
-- Connection from Karlsruhe Hbf, Departuretime 11:59 from track 3 to Berlin Hauptbahnhof, Arrivaltime 18:03 on track 2, with ICE 370
data Connection
= Departure
{ departStation :: Text
, departAt :: Text
, departTrack :: Text
, product :: Text
}
| Arrival
{ arriveStation :: Text
, arriveOn :: Text
, arriveTrack :: Text
, product :: Text
}
deriving (Show)
parseConnection :: Text -> Maybe [Connection]
parseConnection = either (const Nothing) Just . parseOnly parser
where
parser = do
departStation <- string "Strecke von " *> parseUntil ", Abfahrtszeit "
departAt <- parseUntil " von Gleis "
departTrack <- parseUntil " nach "
arriveStation <- parseUntil ", Ankunftszeit "
arriveOn <- parseUntil " auf Gleis "
arriveTrack <- parseUntil ", mit "
product <- takeText
return [Departure {..}, Arrival {..}]
parseUntil :: Text -> Parser Text
parseUntil = fmap pack . manyTill anyChar . string
-- and that's it. Parsing in Haskell is awesome.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment