-- | similar to GenUtil but can rely on non-haskell 98 features module Util.Gen(module Util.Gen, module GenUtil, intercalate) where import Control.Monad.Writer import Data.List import Data.Maybe import System.Directory import Text.ParserCombinators.ReadP import GenUtil hiding(replicateM, intercalate) mconcatMap f xs = mconcat (map f xs) mintercalate x xs = mconcat (intersperse x xs) mconcatMapM f xs = mapM f xs >>= return . mconcat runReadP :: Monad m => ReadP a -> String -> m a runReadP rp s = case [ x | (x,t) <- readP_to_S rp s, ("","") <- lex t] of [x] -> return x [] -> fail "runReadP: no parse" _ -> fail "runReadP: ambiguous parse" runEither :: String -> Either String a -> a runEither msg (Left fm) = error $ msg ++ " - " ++ fm runEither _ (Right a) = a travCollect :: Monoid w => ((a -> Writer w a) -> a -> Writer w a) -> (a -> w) -> a -> w travCollect fn col x = execWriter (f x) where f x = tell (col x) >> fn f x forMn_ xs = forM_ (zip xs [0 :: Int .. ]) forMn xs = forM (zip xs [0 :: Int .. ]) shortenPath :: String -> IO String shortenPath x@('/':_) = do cd <- getCurrentDirectory pwd <- lookupEnv "PWD" h <- lookupEnv "HOME" let f d = do d <- d '/':rest <- getPrefix d x return rest return $ fromJust $ f (return cd) `mplus` f pwd `mplus` liftM ("~/" ++) (f h) `mplus` return x shortenPath x = return x maybeDo :: Monad m => Maybe (m a) -> (m ()) maybeDo x = maybe (return ()) (>> return ()) x