module Lastik.Util( (>>>>), (>>>>>), quote, (>===<), (~~), (~??), (~?), param, many, manys, (~~~~>), (~~~>), (~~>), (-~>), (^^^), space, space', uncons, ifM ) where import System.Exit import Control.Applicative hiding (many) import Control.Monad import Data.Maybe import Data.Monoid import Data.List import System.FilePath -- | Applies the second value only if the first produces @ExitSuccess@. (>>>>) :: (Applicative f) => f ExitCode -> f ExitCode -> f ExitCode (>>>>) = let ExitSuccess `k` q = q p `k` _= p in liftA2 k -- | Executes the second action only if the first produces @ExitSuccess@. (>>>>>) :: (Monad m) => m ExitCode -> m () -> m () p >>>>> q = do e <- p when (e == ExitSuccess) q -- | Surrounds the given string in double-quotes. quote :: String -> String quote s = '"' : s ++ ['"'] -- | Surrounds each string in the list with double-quotes then intercalates the other given value. (>===<) :: String -> [String] -> String s >===< k = intercalate s (fmap quote k) -- | An empty list if the boolean is @False@ otherwise the given string value with @'-'@ prepended. (~~) :: String -> Bool -> String g ~~ k = if k then '-' : g else [] -- | If the given list of file paths is empty, then returns the empty list. Otherwise prepend @'-'@ to the string followed by @' '@ then the search path separator intercalated in the list of file paths. -- -- > Posix -- > "123" ~?? ["abc", "def"] == "-123 \"abc\":\"def\"" -- > "123" ~?? ["abc", "def", "ghi"] == "-123 \"abc\":\"def\":\"ghi\"" (~??) :: String -> [FilePath] -> String s ~?? [] = [] s ~?? z = '-' : s ++ ' ' : [searchPathSeparator] >===< z -- | If the given value is @Nothing@ return the empty list, otherwise run the given function. (~?) :: (k -> [a]) -> Maybe k -> [a] (~?) = maybe [] -- | If the given value is @Nothing@ return the empty list, otherwise prepend @'-'@ to the given string followed by the given character followed by surrounding the result of running the given function in double-quotes. -- -- > param "abc" 'x' id (Just "tuv") == "-abcx\"tuv\"" -- > param "abc" 'x' id Nothing == "" param :: String -> Char -> (k -> String) -> Maybe k -> String param k c s = (~?) (\z -> '-' : k ++ c : quote (s z)) -- | A parameter with many values interspersed by @' '@. -- -- > many "abc" ["tuv", "wxy"] == "-abc \"tuv\" -abc \"wxy\"" many :: String -> [String] -> String many k v = intercalate " " $ map (k ~~~~>) v -- | A parameter with many values interspersed by @' '@. -- -- > manys id "abc" ["tuv", "wxy"] == "-abc \"tuv\" -abc \"wxy\"" manys :: (a -> String) -> String -> [a] -> String manys f k v = many k (map f v) -- | Prepends @'-'@ followed by the first value then @' '@ then the second value surrounded by double-quotes. -- -- > "abc" ~~~~> "def" == "-abc \"def\"" (~~~~>) :: String -> String -> String (~~~~>) = (. Just) . (~~~>) -- | If the given value is @Nothing@ return the empty list, otherwise prepend @'-'@ followed by the first value then @' '@ then the second value surrounded by double-quotes. -- -- > "abc" ~~~> Just "def" == "-abc \"def\"" -- > "abc" ~~~> Nothing == "" (~~~>) :: String -> Maybe String -> String (~~~>) = flip (~~>) id -- | If the given value is @Nothing@ return the empty list, otherwise prepend @'-'@ followed by the first value then @' '@ followed by surrounding the result of running the given function in double-quotes. -- -- > "abc" ~~> id $ Just "def" == "-abc \"def\"" -- > "abc" ~~> id $ Nothing == "" (~~>) :: String -> (k -> String) -> Maybe k -> String (~~>) = flip param ' ' -- | If the given value is @Nothing@ return the empty list, otherwise prepend @'-'@ followed by the first value then @':'@ followed by surrounding the result of running the given function in double-quotes. -- -- > "abc" ~~> id $ Just "def" == "-abc:\"def\"" -- > "abc" ~~> id $ Nothing == "" (-~>) :: String -> (k -> String) -> Maybe k -> String (-~>) = flip param ':' -- | Removes all empty lists from the first argument the intercalates the second argument. -- -- > ["abc", "", "def"] ^^^ "x" == "abcxdef" (^^^) :: [[a]] -> [a] -> [a] g ^^^ t = Data.List.intercalate t (filter (not . null) g) -- | Surrounds each given value in double-quotes then intercalates @' '@. -- -- > space ["abc", "def"] == "\"abc\" \"def\"" space :: [String] -> String space = (>===<) " " -- | Intercalates @' '@. -- -- > space' ["abc", "def"] == "abc def" space' :: [String] -> String space' = intercalate " " -- | If the given list is empty return the first argument, otherwise run the given function on the head and tail. uncons :: a -> (b -> [b] -> a) -> [b] -> a uncons x _ [] = x uncons _ f (h:t) = f h t -- | if/then/else with a lifted predicate. ifM :: (Monad f) => f Bool -> f a -> f a -> f a ifM c t f = do c' <- c t' <- t f' <- f return (if c' then t' else f')