packages feed

eternal-0.1.0: src/Control/Eternal/Algorithms/NaturalSort.hs

{-# LANGUAGE UnicodeSyntax #-}
module Control.Eternal.Algorithms.NaturalSort
  ( nSort
  ) where

import Data.List
import Data.Char

import Control.Eternal.Syntax

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)