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 :: String -> Maybe a
maybeRead = [a] -> Maybe a
forall a. [a] -> Maybe a
listToMaybe ([a] -> Maybe a) -> (String -> [a]) -> String -> Maybe a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((a, String) -> a) -> [(a, String)] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map (a, String) -> a
forall a b. (a, b) -> a
fst ([(a, String)] -> [a])
-> (String -> [(a, String)]) -> String -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [(a, String)]
forall a. Read a => ReadS a
reads
align :: Bool -> Char -> Int -> String -> String
align :: Bool -> Char -> Int -> String -> String
align Bool
left = if Bool
left
then Char -> Int -> String -> String
leftAlign
else Char -> Int -> String -> String
rightAlign
rightAlign :: Char -> Int -> String -> String
rightAlign :: Char -> Int -> String -> String
rightAlign Char
c Int
width String
s | Int
width Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
len = String
s
| Bool
otherwise = Int -> Char -> String
forall a. Int -> a -> [a]
replicate (Int
width Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
len) Char
c String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s
where
len :: Int
len = String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
s
leftAlign :: Char -> Int -> String -> String
leftAlign :: Char -> Int -> String -> String
leftAlign Char
c Int
width String
s | Int
width Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
len = String
s
| Bool
otherwise = String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> Char -> String
forall a. Int -> a -> [a]
replicate (Int
width Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
len) Char
c
where
len :: Int
len = String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
s
showWithBase :: Integral a => Int -> a -> String
showWithBase :: Int -> a -> String
showWithBase Int
b a
0 = String
"0"
showWithBase Int
b a
n | a
n a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
0 = Char
'-'Char -> String -> String
forall a. a -> [a] -> [a]
:Int -> a -> String
forall a. Integral a => Int -> a -> String
showWithBase Int
b (a -> a
forall a. Num a => a -> a
abs a
n)
| Bool
otherwise = (Int -> Char) -> [Int] -> String
forall a b. (a -> b) -> [a] -> [b]
map Int -> Char
intToDigit ([Int] -> String) -> [Int] -> String
forall a b. (a -> b) -> a -> b
$ Int -> a -> [Int]
forall a. Integral a => Int -> a -> [Int]
integerToDigits Int
b a
n
integerToDigits :: Integral a => Int -> a -> [Int]
integerToDigits :: Int -> a -> [Int]
integerToDigits Int
b =
(a -> Int) -> [a] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map a -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral
([a] -> [Int]) -> (a -> [a]) -> a -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> [a]
forall a. [a] -> [a]
reverse
([a] -> [a]) -> (a -> [a]) -> a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Maybe (a, a)) -> a -> [a]
forall b a. (b -> Maybe (a, b)) -> b -> [a]
unfoldr (\a
n -> [(a, a)] -> Maybe (a, a)
forall a. [a] -> Maybe a
listToMaybe [(a, a) -> (a, a)
forall b a. (b, a) -> (a, b)
swap ((a, a) -> (a, a)) -> (a, a) -> (a, a)
forall a b. (a -> b) -> a -> b
$ a
n a -> a -> (a, a)
forall a. Integral a => a -> a -> (a, a)
`divMod` Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
b | a
n a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= a
0])
(a -> [a]) -> (a -> a) -> a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
forall a. Num a => a -> a
abs
where
swap :: (b, a) -> (a, b)
swap (b
x,a
y) = (a
y,b
x)
applyWhen :: Bool -> (a -> a) -> a -> a
applyWhen :: Bool -> (a -> a) -> a -> a
applyWhen Bool
True a -> a
f a
x = a -> a
f a
x
applyWhen Bool
False a -> a
f a
x = a
x
intsToDigits :: [Int] -> String
intsToDigits :: [Int] -> String
intsToDigits = (Int -> Char) -> [Int] -> String
forall a b. (a -> b) -> [a] -> [b]
map Int -> Char
intToDigit
theLast :: Int -> [a] -> [a]
theLast :: Int -> [a] -> [a]
theLast Int
n [a]
xs = Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
drop ([a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n) [a]
xs
loop :: [a] -> [a]
loop :: [a] -> [a]
loop [] = []
loop [a]
xs = [a] -> [a]
forall a. [a] -> [a]
cycle [a]
xs
none :: (a -> Bool) -> [a] -> Bool
none :: (a -> Bool) -> [a] -> Bool
none a -> Bool
p = Bool -> Bool
not (Bool -> Bool) -> ([a] -> Bool) -> [a] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
or ([Bool] -> Bool) -> ([a] -> [Bool]) -> [a] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Bool) -> [a] -> [Bool]
forall a b. (a -> b) -> [a] -> [b]
map a -> Bool
p