extra 1.2 → 1.3
raw patch · 9 files changed
+35/−7 lines, 9 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Control.Exception.Extra: errorIO :: String -> IO a
+ Control.Monad.Extra: whenJustM :: Monad m => m (Maybe a) -> (a -> m ()) -> m ()
+ Extra: errorIO :: String -> IO a
+ Extra: whenJustM :: Monad m => m (Maybe a) -> (a -> m ()) -> m ()
Files
- CHANGES.txt +3/−0
- extra.cabal +1/−1
- src/Control/Concurrent/Extra.hs +1/−0
- src/Control/Exception/Extra.hs +9/−0
- src/Control/Monad/Extra.hs +5/−1
- src/Data/List/Extra.hs +3/−1
- src/Extra.hs +2/−2
- test/TestGen.hs +4/−1
- test/TestUtil.hs +7/−1
CHANGES.txt view
@@ -1,5 +1,8 @@ Changelog for Extra +1.3+ Add whenJustM+ Add errorIO 1.2 Add onceFork Make once async exception safe
extra.cabal view
@@ -1,7 +1,7 @@ cabal-version: >= 1.10 build-type: Simple name: extra-version: 1.2+version: 1.3 license: BSD3 license-file: LICENSE category: Development
src/Control/Concurrent/Extra.hs view
@@ -211,6 +211,7 @@ -- and in some ways is like a manually managed thunk. newtype Barrier a = Barrier (Var (Either (MVar ()) a)) -- Either a Left empty MVar you should wait or a Right result+ -- With base 4.7 and above readMVar is atomic so you probably can implement Barrier directly on MVar a -- | Create a new 'Barrier'. newBarrier :: IO (Barrier a)
src/Control/Exception/Extra.hs view
@@ -6,6 +6,7 @@ module Control.Exception, retry, showException, stringException,+ errorIO, -- * Exception catching/ignoring ignore, catch_, handle_, try_,@@ -47,6 +48,14 @@ -- > ignore (fail "die") == return () ignore :: IO () -> IO () ignore = void . try_+++-- | Like error, but in the 'IO' monad.+-- Note that while 'fail' in 'IO' raises an 'IOException', this function raises an 'ErrorCall' exception.+--+-- > try (errorIO "Hello") == return (Left (ErrorCall "Hello"))+errorIO :: String -> IO a+errorIO = throwIO . ErrorCall -- | Retry an operation at most /n/ times (/n/ must be positive).
src/Control/Monad/Extra.hs view
@@ -6,7 +6,7 @@ -- see <http://hackage.haskell.org/package/monad-loops monad-loops>. module Control.Monad.Extra( module Control.Monad,- whenJust,+ whenJust, whenJustM, unit, -- * Loops loopM, whileM,@@ -30,6 +30,10 @@ -- > whenJust (Just 1) print == print 1 whenJust :: Applicative m => Maybe a -> (a -> m ()) -> m () whenJust mg f = maybe (pure ()) f mg++-- | Like 'whenJust', but where the test can be monadic.+whenJustM :: Monad m => m (Maybe a) -> (a -> m ()) -> m ()+whenJustM mg f = maybe (return ()) f =<< mg -- | The identity function which requires the inner argument to be @()@. Useful for functions -- with overloaded return types.
src/Data/List/Extra.hs view
@@ -317,6 +317,7 @@ -- > breakEnd isLower "youRE" == ("you","RE") -- > breakEnd isLower "youre" == ("youre","") -- > breakEnd isLower "YOURE" == ("","YOURE")+-- > \f xs -> breakEnd (not . f) xs == spanEnd f xs breakEnd :: (a -> Bool) -> [a] -> ([a], [a]) breakEnd f = swap . both reverse . break f . reverse @@ -324,7 +325,8 @@ -- -- > spanEnd isUpper "youRE" == ("you","RE") -- > spanEnd (not . isSpace) "x y z" == ("x y ","z")--- > \f xs-> spanEnd f xs == swap (both reverse (span f (reverse xs)))+-- > \f xs -> uncurry (++) (spanEnd f xs) == xs+-- > \f xs -> spanEnd f xs == swap (both reverse (span f (reverse xs))) spanEnd :: (a -> Bool) -> [a] -> ([a], [a]) spanEnd f = breakEnd (not . f)
src/Extra.hs view
@@ -8,10 +8,10 @@ getNumCapabilities, setNumCapabilities, withNumCapabilities, forkFinally, once, onceFork, Lock, newLock, withLock, withLockTry, Var, newVar, readVar, modifyVar, modifyVar_, withVar, Barrier, newBarrier, signalBarrier, waitBarrier, waitBarrierMaybe, -- * Control.Exception.Extra -- | Extra functions available in @"Control.Exception.Extra"@.- retry, showException, stringException, ignore, catch_, handle_, try_, catchJust_, handleJust_, tryJust_, catchBool, handleBool, tryBool,+ retry, showException, stringException, errorIO, ignore, catch_, handle_, try_, catchJust_, handleJust_, tryJust_, catchBool, handleBool, tryBool, -- * Control.Monad.Extra -- | Extra functions available in @"Control.Monad.Extra"@.- whenJust, unit, loopM, whileM, partitionM, concatMapM, mapMaybeM, findM, firstJustM, whenM, unlessM, ifM, notM, (||^), (&&^), orM, andM, anyM, allM,+ whenJust, whenJustM, unit, loopM, whileM, partitionM, concatMapM, mapMaybeM, findM, firstJustM, whenM, unlessM, ifM, notM, (||^), (&&^), orM, andM, anyM, allM, -- * Data.Either.Extra -- | Extra functions available in @"Data.Either.Extra"@. isLeft, isRight, fromLeft, fromRight, fromEither,
test/TestGen.hs view
@@ -17,6 +17,7 @@ testGen "stringException ['t','e','s','t',undefined] == return \"test<Exception>\"" $ stringException ['t','e','s','t',undefined] == return "test<Exception>" testGen "ignore (print 1) == print 1" $ ignore (print 1) == print 1 testGen "ignore (fail \"die\") == return ()" $ ignore (fail "die") == return ()+ testGen "try (errorIO \"Hello\") == return (Left (ErrorCall \"Hello\"))" $ try (errorIO "Hello") == return (Left (ErrorCall "Hello")) testGen "retry 1 (print \"x\") == print \"x\"" $ retry 1 (print "x") == print "x" testGen "retry 3 (fail \"die\") == fail \"die\"" $ retry 3 (fail "die") == fail "die" testGen "whenJust Nothing print == return ()" $ whenJust Nothing print == return ()@@ -126,9 +127,11 @@ testGen "breakEnd isLower \"youRE\" == (\"you\",\"RE\")" $ breakEnd isLower "youRE" == ("you","RE") testGen "breakEnd isLower \"youre\" == (\"youre\",\"\")" $ breakEnd isLower "youre" == ("youre","") testGen "breakEnd isLower \"YOURE\" == (\"\",\"YOURE\")" $ breakEnd isLower "YOURE" == ("","YOURE")+ testGen "\\f xs -> breakEnd (not . f) xs == spanEnd f xs" $ \f xs -> breakEnd (not . f) xs == spanEnd f xs testGen "spanEnd isUpper \"youRE\" == (\"you\",\"RE\")" $ spanEnd isUpper "youRE" == ("you","RE") testGen "spanEnd (not . isSpace) \"x y z\" == (\"x y \",\"z\")" $ spanEnd (not . isSpace) "x y z" == ("x y ","z")- testGen "\\f xs-> spanEnd f xs == swap (both reverse (span f (reverse xs)))" $ \f xs-> spanEnd f xs == swap (both reverse (span f (reverse xs)))+ testGen "\\f xs -> uncurry (++) (spanEnd f xs) == xs" $ \f xs -> uncurry (++) (spanEnd f xs) == xs+ testGen "\\f xs -> spanEnd f xs == swap (both reverse (span f (reverse xs)))" $ \f xs -> spanEnd f xs == swap (both reverse (span f (reverse xs))) testGen "wordsBy (== ':') \"::xyz:abc::123::\" == [\"xyz\",\"abc\",\"123\"]" $ wordsBy (== ':') "::xyz:abc::123::" == ["xyz","abc","123"] testGen "\\s -> wordsBy isSpace s == words s" $ \s -> wordsBy isSpace s == words s testGen "linesBy (== ':') \"::xyz:abc::123::\" == [\"\",\"\",\"xyz\",\"abc\",\"\",\"123\",\"\"]" $ linesBy (== ':') "::xyz:abc::123::" == ["","","xyz","abc","","123",""]
test/TestUtil.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE ScopedTypeVariables, CPP #-} module TestUtil(runTests, testGen, erroneous, (====), module X) where @@ -23,6 +23,7 @@ import System.Directory as X import System.FilePath as X import System.Info as X+import Control.Exception as X import Test.QuickCheck as X((==>)) @@ -43,6 +44,11 @@ (====) :: (Show a, Eq a) => a -> a -> Bool a ==== b = if a == b then True else error $ "Not equal!\n" ++ show a ++ "\n" ++ show b++#if __GLASGOW_HASKELL__ < 707+instance Eq ErrorCall where+ ErrorCall x == ErrorCall y = x == y+#endif runTests :: IO () -> IO () runTests t = do