eternal-0.0.1: src/Control/Eternal/Algorithms/NaturalSort.hs
module Control.Eternal.Algorithms.NaturalSort
( nSort
) where
import Data.List
import Data.Char
nSort :: [String] -> [String]
nSort s = if all allFloat s then
let { readFloat = read :: String -> Float }
in (map show . sortBy compare . map readFloat) s
else
sortBy natComp s
where allFloat = all (\x -> isDigit x || '.' == 'x')
natComp :: String -> String -> Ordering
natComp [] [] = EQ
natComp [] _ = LT
natComp _ [] = GT
natComp xxs@(x:xs) yys@(y:ys)
| noDigit x && noDigit y && x == y = natComp xs ys
| noDigit x || noDigit y = compare x y
| nx == ny = natComp rx ry
| otherwise = compare nx ny
where (nx,rx) = getNumber xxs
(ny,ry) = getNumber yys
noDigit = not . isDigit
getNumber s = let { digits = takeWhile isDigit s }
in (read digits :: Integer, drop (length digits) s)