extra 1.5 → 1.5.1
raw patch · 8 files changed
+88/−17 lines, 8 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Data.Typeable.Extra: Refl :: (:~:) k b b
- Extra: Refl :: (:~:) k b b
- System.Directory.Extra: withCurrentDirectory :: FilePath -> IO a -> IO a
+ Data.Either.Extra: eitherToMaybe :: Either a b -> Maybe b
+ Data.Either.Extra: fromLeft' :: Either l r -> l
+ Data.Either.Extra: fromRight' :: Either l r -> r
+ Data.Either.Extra: maybeToEither :: a -> Maybe b -> Either a b
+ Data.List.Extra: zipFrom :: Enum a => a -> [b] -> [(a, b)]
+ Data.List.Extra: zipWithFrom :: Enum a => (a -> b -> c) -> a -> [b] -> [c]
+ Data.Tuple.Extra: infixr 3 &&&
+ Data.Typeable.Extra: [Refl] :: (:~:) k a a
+ Extra: [Refl] :: (:~:) k a a
+ Extra: eitherToMaybe :: Either a b -> Maybe b
+ Extra: fromLeft' :: Either l r -> l
+ Extra: fromRight' :: Either l r -> r
+ Extra: infixr 3 &&&
+ Extra: maybeToEither :: a -> Maybe b -> Either a b
+ Extra: zipFrom :: Enum a => a -> [b] -> [(a, b)]
+ Extra: zipWithFrom :: Enum a => (a -> b -> c) -> a -> [b] -> [c]
- Data.Typeable.Extra: Proxy :: Proxy
+ Data.Typeable.Extra: Proxy :: Proxy k
- Data.Typeable.Extra: data (:~:) (a :: k) (b :: k) :: k -> k -> *
+ Data.Typeable.Extra: data (:~:) k (a :: k) (b :: k) :: forall k. k -> k -> *
- Data.Typeable.Extra: data Proxy (t :: k) :: k -> *
+ Data.Typeable.Extra: data Proxy k (t :: k) :: forall k. k -> *
- Extra: Proxy :: Proxy
+ Extra: Proxy :: Proxy k
- Extra: data (:~:) (a :: k) (b :: k) :: k -> k -> *
+ Extra: data (:~:) k (a :: k) (b :: k) :: forall k. k -> k -> *
- Extra: data Proxy (t :: k) :: k -> *
+ Extra: data Proxy k (t :: k) :: forall k. k -> *
Files
- CHANGES.txt +4/−0
- extra.cabal +2/−2
- src/Data/Either/Extra.hs +42/−1
- src/Data/List/Extra.hs +21/−1
- src/Extra.hs +2/−2
- src/System/Time/Extra.hs +2/−7
- test/TestGen.hs +11/−0
- test/TestUtil.hs +4/−4
CHANGES.txt view
@@ -1,5 +1,9 @@ Changelog for Extra +1.5.1+ #25, add zipFrom and zipWithFrom+ #24, add eitherToMaybe and maybeToEither+ Add fromLeft' and fromRight' 1.5 Change fromLeft/fromRight signatures to follow the base libraries 1.4.12
extra.cabal view
@@ -1,7 +1,7 @@-cabal-version: >= 1.10+cabal-version: >= 1.18 build-type: Simple name: extra-version: 1.5+version: 1.5.1 license: BSD3 license-file: LICENSE category: Development
src/Data/Either/Extra.hs view
@@ -6,7 +6,9 @@ -- partial, and should be used with care in production-quality code. module Data.Either.Extra( module Data.Either,- isLeft, isRight, fromLeft, fromRight, fromEither+ isLeft, isRight, fromLeft, fromRight, fromEither,+ fromLeft', fromRight',+ eitherToMaybe, maybeToEither, ) where import Data.Either@@ -32,6 +34,28 @@ #endif ++-- | The 'fromLeft'' function extracts the element out of a 'Left' and+-- throws an error if its argument is 'Right'.+-- Much like 'fromJust', using this function in polished code is usually a bad idea.+--+-- > \x -> fromLeft' (Left x) == x+-- > \x -> fromLeft' (Right x) == undefined+fromLeft' :: Either l r -> l+fromLeft' (Left x) = x+fromLeft' _ = error "fromLeft', given a Right"++-- | The 'fromRight'' function extracts the element out of a 'Right' and+-- throws an error if its argument is 'Left'.+-- Much like 'fromJust', using this function in polished code is usually a bad idea.+--+-- > \x -> fromRight' (Right x) == x+-- > \x -> fromRight' (Left x) == undefined+fromRight' :: Either l r -> r+fromRight' (Right x) = x+fromRight' _ = error "fromRight', given a Left"++ #if __GLASGOW_HASKELL__ < 708 -- | Test if an 'Either' value is the 'Left' constructor. -- Provided as standard with GHC 7.8 and above.@@ -51,3 +75,20 @@ -- > \x -> fromEither (Right x) == x fromEither :: Either a a -> a fromEither = either id id+++-- | Given a 'Maybe', convert it to an 'Either', providing a suitable+-- value for the 'Left' should the value be 'Nothing'.+--+-- > \a b -> maybeToEither a (Just b) == Right b+-- > \a -> maybeToEither a Nothing == Left a+maybeToEither :: a -> Maybe b -> Either a b+maybeToEither a (Just b) = Right b+maybeToEither a Nothing = Left a++-- | Given an 'Either', convert it to a 'Maybe', where 'Left' becomes 'Nothing'.+--+-- > \x -> eitherToMaybe (Left x) == Nothing+-- > \x -> eitherToMaybe (Right x) == Just x+eitherToMaybe :: Either a b -> Maybe b+eitherToMaybe = either (const Nothing) Just
src/Data/List/Extra.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE CPP, TupleSections #-}+{-# LANGUAGE CPP, TupleSections, BangPatterns #-} {-# OPTIONS_GHC -fno-warn-duplicate-exports #-} -- | This module extends "Data.List" with extra functions of a similar nature.@@ -24,6 +24,7 @@ disjoint, allSame, anySame, repeatedly, for, firstJust, concatUnzip, concatUnzip3,+ zipFrom, zipWithFrom, replace, merge, mergeBy, ) where @@ -171,6 +172,25 @@ splitAtEnd i xs = f xs (drop i xs) where f (x:xs) (y:ys) = first (x:) $ f xs ys f xs _ = ([], xs)+++-- | 'zip' against an enumeration.+-- Never truncates the output - raises an error if the enumeration runs out.+--+-- > \i xs -> zip [i..] xs == zipFrom i xs+-- > zipFrom False [1..3] == undefined+zipFrom :: Enum a => a -> [b] -> [(a, b)]+zipFrom = zipWithFrom (,)++-- | 'zipFrom' generalised to any combining operation.+--+-- > \i xs -> zipWithFrom (,) i xs == zipFrom i xs+zipWithFrom :: Enum a => (a -> b -> c) -> a -> [b] -> [c]+zipWithFrom f a xs = go a xs+ where+ -- if we aren't strict in the accumulator, it's highly like to be a space leak+ go !a [] = []+ go !a (x:xs) = f a x : go (succ a) xs -- | A merging of 'unzip' and 'concat'.
src/Extra.hs view
@@ -17,13 +17,13 @@ whenJust, whenJustM, unit, maybeM, eitherM, loopM, whileM, partitionM, concatMapM, concatForM, mconcatMapM, 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,+ isLeft, isRight, fromLeft, fromRight, fromEither, fromLeft', fromRight', eitherToMaybe, maybeToEither, -- * Data.IORef.Extra -- | Extra functions available in @"Data.IORef.Extra"@. modifyIORef', writeIORef', atomicModifyIORef', atomicWriteIORef, atomicWriteIORef', -- * Data.List.Extra -- | Extra functions available in @"Data.List.Extra"@.- lower, upper, trim, trimStart, trimEnd, word1, line1, dropEnd, takeEnd, splitAtEnd, breakEnd, spanEnd, dropWhileEnd, dropWhileEnd', takeWhileEnd, stripSuffix, stripInfix, stripInfixEnd, wordsBy, linesBy, breakOn, breakOnEnd, splitOn, split, chunksOf, list, uncons, unsnoc, cons, snoc, drop1, mconcatMap, groupSort, groupSortOn, groupSortBy, nubOrd, nubOrdBy, nubOrdOn, nubOn, groupOn, sortOn, disjoint, allSame, anySame, repeatedly, for, firstJust, concatUnzip, concatUnzip3, replace, merge, mergeBy,+ lower, upper, trim, trimStart, trimEnd, word1, line1, dropEnd, takeEnd, splitAtEnd, breakEnd, spanEnd, dropWhileEnd, dropWhileEnd', takeWhileEnd, stripSuffix, stripInfix, stripInfixEnd, wordsBy, linesBy, breakOn, breakOnEnd, splitOn, split, chunksOf, list, uncons, unsnoc, cons, snoc, drop1, mconcatMap, groupSort, groupSortOn, groupSortBy, nubOrd, nubOrdBy, nubOrdOn, nubOn, groupOn, sortOn, disjoint, allSame, anySame, repeatedly, for, firstJust, concatUnzip, concatUnzip3, zipFrom, zipWithFrom, replace, merge, mergeBy, -- * Data.Tuple.Extra -- | Extra functions available in @"Data.Tuple.Extra"@. first, second, (***), (&&&), dupe, both, fst3, snd3, thd3,
src/System/Time/Extra.hs view
@@ -17,7 +17,6 @@ import Data.Time.Clock import System.Clock import Numeric.Extra-import Data.IORef import Control.Monad.Extra import Control.Exception.Extra import Data.Typeable@@ -73,6 +72,7 @@ (\_ -> fmap Just f)) +-- Once we remove subtractTime we can remove the dependency on the time package entire. {-# DEPRECATED subtractTime "Function is being retired - use diffUTCTime directly." #-} -- | Calculate the difference between two times in seconds.@@ -115,12 +115,7 @@ -- | A synonym for 'offsetTime'. offsetTimeIncrease :: IO (IO Seconds)-offsetTimeIncrease = do- t <- offsetTime- ref <- newIORef 0- return $ do- t <- t- atomicModifyIORef ref $ \o -> let m = max t o in m `seq` (m, m)+offsetTimeIncrease = offsetTime -- | Record how long a computation takes in 'Seconds'. --
test/TestGen.hs view
@@ -53,8 +53,16 @@ testGen "fromLeft 1 (Right \"foo\") == 1" $ fromLeft 1 (Right "foo") == 1 testGen "fromRight 1 (Right 3) == 3" $ fromRight 1 (Right 3) == 3 testGen "fromRight 1 (Left \"foo\") == 1" $ fromRight 1 (Left "foo") == 1+ testGen "\\x -> fromLeft' (Left x) == x" $ \x -> fromLeft' (Left x) == x+ testGen "\\x -> fromLeft' (Right x) == undefined" $ \x -> erroneous $ fromLeft' (Right x)+ testGen "\\x -> fromRight' (Right x) == x" $ \x -> fromRight' (Right x) == x+ testGen "\\x -> fromRight' (Left x) == undefined" $ \x -> erroneous $ fromRight' (Left x) testGen "\\x -> fromEither (Left x ) == x" $ \x -> fromEither (Left x ) == x testGen "\\x -> fromEither (Right x) == x" $ \x -> fromEither (Right x) == x+ testGen "\\a b -> maybeToEither a (Just b) == Right b" $ \a b -> maybeToEither a (Just b) == Right b+ testGen "\\a -> maybeToEither a Nothing == Left a" $ \a -> maybeToEither a Nothing == Left a+ testGen "\\x -> eitherToMaybe (Left x) == Nothing" $ \x -> eitherToMaybe (Left x) == Nothing+ testGen "\\x -> eitherToMaybe (Right x) == Just x" $ \x -> eitherToMaybe (Right x) == Just x testGen "\\xs -> repeatedly (splitAt 3) xs == chunksOf 3 xs" $ \xs -> repeatedly (splitAt 3) xs == chunksOf 3 xs testGen "\\xs -> repeatedly word1 (trim xs) == words xs" $ \xs -> repeatedly word1 (trim xs) == words xs testGen "\\xs -> repeatedly line1 xs == lines xs" $ \xs -> repeatedly line1 xs == lines xs@@ -100,6 +108,9 @@ testGen "splitAtEnd 3 \"he\" == (\"\", \"he\")" $ splitAtEnd 3 "he" == ("", "he") testGen "\\i xs -> uncurry (++) (splitAt i xs) == xs" $ \i xs -> uncurry (++) (splitAt i xs) == xs testGen "\\i xs -> splitAtEnd i xs == (dropEnd i xs, takeEnd i xs)" $ \i xs -> splitAtEnd i xs == (dropEnd i xs, takeEnd i xs)+ testGen "\\i xs -> zip [i..] xs == zipFrom i xs" $ \i xs -> zip [i..] xs == zipFrom i xs+ testGen "zipFrom False [1..3] == undefined" $ erroneous $ zipFrom False [1..3]+ testGen "\\i xs -> zipWithFrom (,) i xs == zipFrom i xs" $ \i xs -> zipWithFrom (,) i xs == zipFrom i xs testGen "concatUnzip [(\"a\",\"AB\"),(\"bc\",\"C\")] == (\"abc\",\"ABC\")" $ concatUnzip [("a","AB"),("bc","C")] == ("abc","ABC") testGen "concatUnzip3 [(\"a\",\"AB\",\"\"),(\"bc\",\"C\",\"123\")] == (\"abc\",\"ABC\",\"123\")" $ concatUnzip3 [("a","AB",""),("bc","C","123")] == ("abc","ABC","123") testGen "takeWhileEnd even [2,3,4,6] == [4,6]" $ takeWhileEnd even [2,3,4,6] == [4,6]
test/TestUtil.hs view
@@ -47,11 +47,11 @@ modifyIORef testCount (+1) -erroneous :: a -> Bool-erroneous x = unsafePerformIO $ fmap isLeft $ try_ $ evaluate x+erroneous :: Show a => a -> Bool+erroneous x = unsafePerformIO $ fmap isLeft $ try_ $ evaluate $ length $ show x -erroneousIO :: IO a -> Bool-erroneousIO x = unsafePerformIO $ fmap isLeft $ try_ $ evaluate =<< x+erroneousIO :: Show a => IO a -> Bool+erroneousIO x = unsafePerformIO $ fmap isLeft $ try_ $ evaluate . length . show =<< x (====) :: (Show a, Eq a) => a -> a -> Bool a ==== b = if a == b then True else error $ "Not equal!\n" ++ show a ++ "\n" ++ show b