module Haskell.X where
import Prelude
import Data.Char
import Data.List
import Data.Ord
import Control.Arrow
exhaustively :: Eq a => (a -> a) -> a -> a
exhaustively = exhaustivelyBy (==)
exhaustivelyBy :: (a -> a -> Bool) -> (a -> a) -> a -> a
exhaustivelyBy predicate func dat = case predicate dat result of
True -> result
False -> exhaustivelyBy predicate func result
where result = func dat
exhaustivelyM :: (Eq a, Monad m) => (a -> m a) -> a -> m a
exhaustivelyM = exhaustivelyByM (==)
exhaustivelyByM :: Monad m => (a -> a -> Bool) -> (a -> m a) -> a -> m a
exhaustivelyByM predicate func dat = do
result <- func dat
case predicate dat result of
True -> return result
False -> exhaustivelyByM predicate func result
uniqSort :: (Ord a) => [a] -> [a]
uniqSort = map head . group . sort
aggregateBy :: (a -> a -> Ordering) -> [a] -> [[a]]
aggregateBy x = groupBy (\a b -> x a b == EQ) . sortBy x
aggregate :: (Ord a) => [a] -> [[a]]
aggregate = aggregateBy compare
aggregateAL :: (Ord a) => [(a,b)] -> [(a,[b])]
aggregateAL = map (fst . head &&& map snd) . aggregateBy (comparing fst)
tr :: Eq a => a -> a -> [a] -> [a]
tr n r (x:xs)
| x == n = r : tr n r xs
| otherwise = x : tr n r xs
tr _ _ [] = []
count4 :: [[[[a]]]] -> Int
count4 = sum . map (sum . map (sum . map length))
count3 :: [[[a]]] -> Int
count3 = sum . map (sum . map length)
count2 :: [[a]] -> Int
count2 = sum . map length
count1 :: [a] -> Int
count1 = length
segment3 :: Int -> [[[a]]] -> [[a]]
segment3 _ [] = []
segment3 size as = if null segments then [concatMap concat as]
else concatMap concat segment : segment3 size rest
where
segmentations = zip (inits as) (tails as)
segments = dropWhile ((< size) . count3 . fst) segmentations
(segment, rest) = head segments
segment2 :: Int -> [[a]] -> [[a]]
segment2 _ [] = []
segment2 size as = if null segments then [concat as]
else concat segment : segment2 size rest
where
segmentations = zip (inits as) (tails as)
segments = dropWhile ((< size) . count2 . fst) segmentations
(segment, rest) = head segments
breakLast :: [a] -> ([a], a)
breakLast [a] = ([], a)
breakLast (a:as) =
let (init', last') = breakLast as
in (a:init', last')
breakLast _ = error "Haskell.X.breakLast: empty list"
uneither :: Either a a -> a
uneither = either id id
data Version = Version {
versionBranch :: [Integer],
versionTags :: [String]
} deriving (Eq, Ord)
instance Read Version where
readsPrec _ = parseVersion
instance Show Version where
showsPrec _ (Version branch tags) xs
= tail (concatMap (('.':) . show) branch) ++ concatMap ('-':) tags ++ xs
parseVersion :: String -> [(Version, String)]
parseVersion string =
let (digits, tagRest) = parseBranch string
(tags, rest) = parseTags tagRest
in if null digits then [] else [(Version (map read digits) tags, rest)]
where
parseBranch str =
let next = span isDigit str
in case next of
("", rest) -> ([], rest)
(ds, '.':rest) -> let (dss, rest') = parseBranch rest
in (ds : dss, rest')
(ds, rest) -> ([ds], rest)
parseTags ('-':str) =
let next = span isAlphaNum str
in case next of
("", rest) -> ([], rest)
(xs, rest) -> let (xss, rest') = parseTags rest
in (xs : xss, rest')
parseTags xs = ([], xs)