{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE CPP #-} {-# LANGUAGE NoMonomorphismRestriction #-} module Buchhaltung.Utils where import Control.Arrow import qualified Control.Exception.Lifted as E import Control.Monad import Control.Monad.IO.Class import Control.Monad.Trans.Control import qualified Data.ListLike as L import Data.Monoid import Data.String import System.Directory import System.IO import qualified System.IO.Temp as T import System.Process -- | apply a funtion to the ith element of a list modifyNth :: (a -> a) -> Int -> [a] -> [a] modifyNth f n = zipWith z [0..] where z i | i == n = f | otherwise = id fshow :: (Show a, IsString b) => a -> b fshow = fromString . show intercalateL :: (L.ListLike a item, L.ListLike b a) => a -> b -> a intercalateL x = L.concat . L.intersperse x map2 :: Arrow a => a b' c' -> a (b', b') (c', c') map2 = join (***) -- withTempFileM :: (MonadIO m, MonadBaseControl IO m) -- => FilePath -> IOMode -> (Handle -> m r) -> m r -- withTempFileM name mode = E.bracket (liftIO $ openFile name mode) -- (liftIO . hClose) withFileM :: (MonadIO m, MonadBaseControl IO m) => FilePath -> IOMode -> (Handle -> m r) -> m r withFileM name mode = E.bracket (liftIO $ openFile name mode) (liftIO . hClose) #if ! MIN_VERSION_base(4,9,0) instance Monoid a => Monoid (IO a) where mempty = pure mempty mappend = liftM2 mappend #endif -- * Ported from 'System.IO.Temp' to work with 'MonadBaseControl' withSystemTempFile template action = liftIO getTemporaryDirectory >>= \tmpDir -> withTempFile tmpDir template action withSystemTempDirectory template action = liftIO getTemporaryDirectory >>= \tmpDir -> withTempDirectory tmpDir template action withTempDirectory targetDir template = E.bracket (liftIO (T.createTempDirectory targetDir template)) (liftIO . ignoringIOErrors . removeDirectoryRecursive) withTempFile tmpDir template action = E.bracket (liftIO (openTempFile tmpDir template)) (\(name, handle) -> liftIO (hClose handle >> ignoringIOErrors (removeFile name))) (uncurry action) ignoringIOErrors :: MonadBaseControl IO m => m () -> m () ignoringIOErrors ioe = ioe `E.catch` (\e -> const (return ()) (e :: IOError)) mconcat' :: Monoid t => [t] -> t mconcat' [] = mempty mconcat' x = foldr1 mappend x (<&>) :: Functor f => (a -> b) -> f a -> f b (<&>) = (<$>) infixr 0 <&> readProcess' :: FilePath -> [String] -> IO String readProcess' x y = readProcess x y ""