versionSort :: [String] -> [String]versionSort = sortOn brkNDwheretr f g (x,y) = f x : g y-- ND for non-digitsbrkND = tr Right brkD . span (not . isDigit)brkD = tr (Left . read @Int) brkND . span isDigit
(side question: does the helper function tr I defined above have a commonly known name?)
I don't think so, but that's just because you made the cut at a
weird point. It's very close to (***)
from Control.Arrow, Data.Tuple.Extra, Data.Profunctor,
and other libraries, also known as bimap
in Data.Bifunctor and in the lens package.
Rewriting your functions to tease it out even more (not tested):
versionSort :: [String] -> [String] versionSort = sortOn gatherNonDigits where gatherAll predicate gather continue = uncurry (:) . (gather *** continue) . span predicate -- 'NonDigits' for non-digits gatherNonDigits = gatherAll (not . isDigit) wrapNonDigits gatherDigits gatherDigits = gatherAll isDigit wrapDigits gatherNonDigits wrapNonDigits = Right wrapDigits = Left . read @Int