-- Copyright (C) 2014 by Alexandru Cojocaru -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation, either version 3 of the License, or -- (at your option) any later version. -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . import Data.List data Semver = Semver { major :: Int, minor :: Int, patch :: Int, label :: String } deriving (Eq) instance Ord Semver where compare x y = if c == EQ then compare (null $ label x) (null $ label y) else c where c = compare [major x, minor x, patch x] [major y, minor y, patch y] instance Show Semver where show s = concat $ [show (major s), ".", show (minor s), ".", show (patch s), label s] instance Read Semver where readsPrec _ xs = let (maj,ys) = span (/= '.') xs in let (min,ws) = span (/= '.') (tail ys) in let (pat,zs) = span (/= '-') (tail ws) in let label = zs in [(Semver{major=read maj,minor=read min,patch=read pat,label=label}, "")] main = interact (unlines . (map show) . sort . ((map read)::[String] -> [Semver]) . lines)