packages feed

extra 1.6.17 → 1.6.18

raw patch · 5 files changed

+47/−10 lines, 5 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Data.List.Extra: maximumOn :: Ord b => (a -> b) -> [a] -> a
+ Data.List.Extra: maximumOn :: (Partial, Ord b) => (a -> b) -> [a] -> a
- Data.List.Extra: minimumOn :: Ord b => (a -> b) -> [a] -> a
+ Data.List.Extra: minimumOn :: (Partial, Ord b) => (a -> b) -> [a] -> a
- Extra: maximumOn :: Ord b => (a -> b) -> [a] -> a
+ Extra: maximumOn :: (Partial, Ord b) => (a -> b) -> [a] -> a
- Extra: minimumOn :: Ord b => (a -> b) -> [a] -> a
+ Extra: minimumOn :: (Partial, Ord b) => (a -> b) -> [a] -> a

Files

CHANGES.txt view
@@ -1,5 +1,8 @@ Changelog for Extra +1.6.18, released 2019-08-21+    Make errorIO include a call stack+    Make maximumOn and minimumOn apply the function once per element 1.6.17, released 2019-05-31     Add enumerate 1.6.16, released 2019-05-25
extra.cabal view
@@ -1,7 +1,7 @@ cabal-version:      >= 1.18 build-type:         Simple name:               extra-version:            1.6.17+version:            1.6.18 license:            BSD3 license-file:       LICENSE category:           Development
src/Control/Exception/Extra.hs view
@@ -21,6 +21,10 @@     catchBool, handleBool, tryBool     ) where +#if __GLASGOW_HASKELL__ >= 800+import GHC.Stack+#endif+ import Control.Exception import Control.Monad import Data.List.Extra@@ -68,11 +72,16 @@   -- | Like error, but in the 'IO' monad.---   Note that while 'fail' in 'IO' raises an 'IOException', this function raises an 'ErrorCall' exception.+--   Note that while 'fail' in 'IO' raises an 'IOException', this function raises an 'ErrorCall' exception with a call stack. ----- > try (errorIO "Hello") == return (Left (ErrorCall "Hello"))+-- > catch (errorIO "Hello") (\(ErrorCall x) -> return x) == return "Hello" errorIO :: Partial => String -> IO a-errorIO = throwIO . ErrorCall+errorIO x = withFrozenCallStack $ evaluate $ error x++#if __GLASGOW_HASKELL__ < 800+withFrozenCallStack :: a -> a+withFrozenCallStack = id+#endif   -- | Retry an operation at most /n/ times (/n/ must be positive).
src/Data/List/Extra.hs view
@@ -364,12 +364,33 @@ nubOn f = map snd . nubBy ((==) `on` fst) . map (\x -> let y = f x in y `seq` (y, x))  -- | A version of 'maximum' where the comparison is done on some extracted value.-maximumOn :: Ord b => (a -> b) -> [a] -> a-maximumOn f = maximumBy (compare `on` f)+--   Raises an error if the list is empty. Only calls the function once per element.+--+-- > maximumOn id [] == undefined+-- > maximumOn length ["test","extra","a"] == "extra"+maximumOn :: (Partial, Ord b) => (a -> b) -> [a] -> a+maximumOn f [] = error "Data.List.Extra.maximumOn: empty list"+maximumOn f (x:xs) = g x (f x) xs+    where+        g v mv [] = v+        g v mv (x:xs) | mx > mv = g x mx xs+                      | otherwise = g v mv xs+            where mx = f x --- | A version of 'minimum' where the comparison is done on some extracted value.-minimumOn :: Ord b => (a -> b) -> [a] -> a-minimumOn f = minimumBy (compare `on` f)++-- | A version of 'maximum' where the comparison is done on some extracted value.+--   Raises an error if the list is empty. Only calls the function once per element.+--+-- > minimumOn id [] == undefined+-- > minimumOn length ["test","extra","a"] == "a"+minimumOn :: (Partial, Ord b) => (a -> b) -> [a] -> a+minimumOn f [] = error "Data.List.Extra.minimumOn: empty list"+minimumOn f (x:xs) = g x (f x) xs+    where+        g v mv [] = v+        g v mv (x:xs) | mx < mv = g x mx xs+                      | otherwise = g v mv xs+            where mx = f x  -- | A combination of 'group' and 'sort'. --
test/TestGen.hs view
@@ -20,7 +20,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 "catch (errorIO \"Hello\") (\\(ErrorCall x) -> return x) == return \"Hello\"" $ catch (errorIO "Hello") (\(ErrorCall x) -> return x) == return "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 ()@@ -149,6 +149,10 @@     testGen "escapeJSON \"\\ttab\\nnewline\\\\\" == \"\\\\ttab\\\\nnewline\\\\\\\\\"" $ escapeJSON "\ttab\nnewline\\" == "\\ttab\\nnewline\\\\"     testGen "escapeJSON \"\\ESC[0mHello\" == \"\\\\u001b[0mHello\"" $ escapeJSON "\ESC[0mHello" == "\\u001b[0mHello"     testGen "\\xs -> unescapeJSON (escapeJSON xs) == xs" $ \xs -> unescapeJSON (escapeJSON xs) == xs+    testGen "maximumOn id [] == undefined" $ erroneous $ maximumOn id []+    testGen "maximumOn length [\"test\",\"extra\",\"a\"] == \"extra\"" $ maximumOn length ["test","extra","a"] == "extra"+    testGen "minimumOn id [] == undefined" $ erroneous $ minimumOn id []+    testGen "minimumOn length [\"test\",\"extra\",\"a\"] == \"a\"" $ minimumOn length ["test","extra","a"] == "a"     testGen "groupSort [(1,'t'),(3,'t'),(2,'e'),(2,'s')] == [(1,\"t\"),(2,\"es\"),(3,\"t\")]" $ groupSort [(1,'t'),(3,'t'),(2,'e'),(2,'s')] == [(1,"t"),(2,"es"),(3,"t")]     testGen "\\xs -> map fst (groupSort xs) == sort (nub (map fst xs))" $ \xs -> map fst (groupSort xs) == sort (nub (map fst xs))     testGen "\\xs -> concatMap snd (groupSort xs) == map snd (sortOn fst xs)" $ \xs -> concatMap snd (groupSort xs) == map snd (sortOn fst xs)