diff options
Diffstat (limited to 'Haskell-book/24/ParserExercises/src/SemVer.hs')
| -rw-r--r-- | Haskell-book/24/ParserExercises/src/SemVer.hs | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/Haskell-book/24/ParserExercises/src/SemVer.hs b/Haskell-book/24/ParserExercises/src/SemVer.hs new file mode 100644 index 0000000..47b49ab --- /dev/null +++ b/Haskell-book/24/ParserExercises/src/SemVer.hs @@ -0,0 +1,51 @@ +module SemVer where + +import Control.Applicative +import Text.Trifecta + +-- 1. Write a parser for semantic versions as defined by http://semver.org/. +-- After making a working parser, write an Ord instance for the SemVer type +-- that obeys the specification outlined on the SemVer website. + +-- Relevant to precedence/ordering, +-- cannot sort numbers like strings. +data NumberOrString = NOSS String + | NOSI Integer + deriving (Eq, Show) + +type Major = Integer +type Minor = Integer +type Patch = Integer +type Release = [NumberOrString] +type Metadata = [NumberOrString] + +data SemVer = SemVer Major Minor Patch Release Metadata + deriving (Eq, Show) + +parseNos :: Parser NumberOrString +parseNos = do + nos <- (NOSI <$> integer) + <|> (NOSS <$> some letter) + return nos + +parseRelease :: Parser [NumberOrString] +parseRelease = do + _ <- char '-' + sepBy parseNos (char '.') + +parseMetadata :: Parser [NumberOrString] +parseMetadata = do + _ <- char '+' + sepBy parseNos (char '.') + +parseSemVer :: Parser SemVer +parseSemVer = do + major <- decimal + _ <- char '.' + minor <- decimal + _ <- char '.' + patch <- decimal + release <- option [] parseRelease + metadata <- option [] parseMetadata + + return $ SemVer major minor patch release metadata |
