module Text.PercentFormat.Utils
( maybeRead
, align
, rightAlign
, leftAlign
, showWithBase
, applyWhen
, intsToDigits
, theLast
, loop
, none
, integerToDigits
)
where
import Data.Maybe (listToMaybe)
import Data.List (unfoldr)
import Data.Char (intToDigit)
maybeRead :: Read a => String -> Maybe a
maybeRead = listToMaybe . map fst . reads
align :: Bool -> Char -> Int -> String -> String
align left = if left
then leftAlign
else rightAlign
rightAlign :: Char -> Int -> String -> String
rightAlign c width s | width <= len = s
| otherwise = replicate (width - len) c ++ s
where
len = length s
leftAlign :: Char -> Int -> String -> String
leftAlign c width s | width <= len = s
| otherwise = s ++ replicate (width - len) c
where
len = length s
showWithBase :: Integral a => Int -> a -> String
showWithBase b 0 = "0"
showWithBase b n | n < 0 = '-':showWithBase b (abs n)
| otherwise = map intToDigit $ integerToDigits b n
integerToDigits :: Integral a => Int -> a -> [Int]
integerToDigits b =
map fromIntegral
. reverse
. unfoldr (\n -> listToMaybe [swap $ n `divMod` fromIntegral b | n /= 0])
. abs
where
swap (x,y) = (y,x)
applyWhen :: Bool -> (a -> a) -> a -> a
applyWhen True f x = f x
applyWhen False f x = x
intsToDigits :: [Int] -> String
intsToDigits = map intToDigit
theLast :: Int -> [a] -> [a]
theLast n xs = drop (length xs - n) xs
loop :: [a] -> [a]
loop [] = []
loop xs = cycle xs
none :: (a -> Bool) -> [a] -> Bool
none p = not . or . map p