module General.Extra(
whenLeft,
whenRightM,
createDirectoryRecursive,
NoShow(..),
memoIO
) where
import Control.Exception.Extra
import System.Directory
import Data.IORef
import qualified Data.HashMap.Strict as Map
import Data.Hashable
import Control.Monad
newtype NoShow a = NoShow a
instance Show (NoShow a) where show _ = "NoShow"
whenRightM :: Monad m => m (Either l r) -> (r -> m ()) -> m ()
whenRightM x act = either (const $ return ()) act =<< x
tryIO :: IO a -> IO (Either IOException a)
tryIO = try
createDirectoryRecursive :: FilePath -> IO ()
createDirectoryRecursive dir = do
x <- tryIO $ doesDirectoryExist dir
when (x /= Right True) $ createDirectoryIfMissing True dir
whenLeft :: Applicative m => Either a b -> (a -> m ()) -> m ()
whenLeft x f = either f (const $ pure ()) x
memoIO :: (Hashable k, Eq k) => (k -> IO v) -> IO (k -> IO v)
memoIO f = do
ref <- newIORef Map.empty
return $ \k -> do
mp <- readIORef ref
case Map.lookup k mp of
Just v -> return v
Nothing -> do
v <- f k
atomicModifyIORef ref $ \mp -> (Map.insert k v mp, v)