-- | Useful functions for working with English-related 'String's.
module Utils.Drasil.English (capitalize, stringList) where
    
import Data.Char (toLower, toUpper)

-- | String capitalization.
capitalize :: String -> String
capitalize :: String -> String
capitalize [] = forall a. HasCallStack => String -> a
error String
"capitalize called on an empty String"
capitalize (Char
c:String
cs) = Char -> Char
toUpper Char
cforall a. a -> [a] -> [a]
:forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower String
cs

-- | Comma separated list with "and" before final item.
stringList :: [String] -> String
stringList :: [String] -> String
stringList [String]
s = [String] -> String
mkStr (forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t a -> Bool
null) [String]
s)
  where
    mkStr :: [String] -> String
    mkStr :: [String] -> String
mkStr []       = String
""
    mkStr [String
d]      = String
d
    mkStr [String
d1, String
d2] = String
d1 forall a. [a] -> [a] -> [a]
++ String
" and " forall a. [a] -> [a] -> [a]
++ String
d2 -- TODO: When you have a list of >=3 items, your last 2 should still have a comma between them.
    mkStr (String
d:[String]
ds)   = String
d forall a. [a] -> [a] -> [a]
++ [String] -> String
manyStrs [String]
ds
    
    manyStrs :: [String] -> String
    manyStrs :: [String] -> String
manyStrs []     = forall a. HasCallStack => String -> a
error String
"impossible case in manyStrs" -- TODO: Make explicit why this is an impossible case
    manyStrs [String
d]    = String
", and " forall a. [a] -> [a] -> [a]
++ String
d
    manyStrs (String
d:[String]
ds) = String
", " forall a. [a] -> [a] -> [a]
++ String
d forall a. [a] -> [a] -> [a]
++ [String] -> String
manyStrs [String]
ds