-- | General-purpose utilities and standard imports. module Util (module Util, module X) where import Control.Applicative as X ((<**>)) import Control.Monad as X ((<=<), filterM, forM, forM_, guard, unless, when) import Control.Monad.IO.Class as X (MonadIO, liftIO) import Control.Monad.Writer as X (WriterT, runWriterT, tell) import Data.Bifunctor as X import Data.Char as X (isSpace) import Data.Function as X (on) import Data.List as X (findIndex, findIndices, intercalate) import Data.List.Split as X (splitWhen) import Data.Maybe as X import Data.Map as X (Map) import Data.Semigroup as X (Semigroup(..)) import Data.Version as X (Version(..)) import System.Directory as X (doesDirectoryExist, listDirectory, removeDirectoryRecursive) import System.Exit as X (die, ExitCode(..)) import System.FilePath as X (()) import System.Process as X (readProcessWithExitCode) import Text.Read as X (readMaybe) (<&>) :: Functor f => f a -> (a -> b) -> f b (<&>) = flip (<$>) forMM :: (Monad m, Monoid b) => m [a] -> (a -> m b) -> m b forMM m k = mconcat <$> do mapM k =<< m unlessM :: Monad m => m Bool -> m () -> m () unlessM cond m = cond >>= (`unless` m) findIndexEnd :: Eq a => (a -> Bool) -> [a] -> Maybe Int findIndexEnd p = lastMaybe . findIndices p lastMaybe :: [a] -> Maybe a lastMaybe [] = Nothing lastMaybe (a:as) = Just $ last1 a as last1 :: a -> [a] -> a last1 a [] = a last1 _ (a:as) = last1 a as