packages feed

extra 1.7.10 → 1.7.11

raw patch · 13 files changed

+72/−16 lines, 13 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Data.List.Extra: groupOnKey :: Eq k => (a -> k) -> [a] -> [(k, [a])]
+ Data.List.Extra: repeatedlyNE :: (NonEmpty a -> (b, [a])) -> [a] -> [b]
+ Data.List.NonEmpty.Extra: foldl1' :: (a -> a -> a) -> NonEmpty a -> a
+ Data.List.NonEmpty.Extra: repeatedly :: (NonEmpty a -> (b, [a])) -> NonEmpty a -> NonEmpty b
+ Extra: groupOnKey :: Eq k => (a -> k) -> [a] -> [(k, [a])]
+ Extra: repeatedlyNE :: (NonEmpty a -> (b, [a])) -> [a] -> [b]
- Data.List.Extra: groupOn :: Eq b => (a -> b) -> [a] -> [[a]]
+ Data.List.Extra: groupOn :: Eq k => (a -> k) -> [a] -> [[a]]
- Extra: groupOn :: Eq b => (a -> b) -> [a] -> [[a]]
+ Extra: groupOn :: Eq k => (a -> k) -> [a] -> [[a]]

Files

CHANGES.txt view
@@ -1,5 +1,9 @@ Changelog for Extra +1.7.11, released 2022-08-21+    #95, add List.repeatedlyNE and NonEmpty.repeatedly+    #94, add groupOnKey+    #91, add foldl1' to NonEmpty 1.7.10, released 2021-08-29     #81, add assertIO function     #85, add !? to do !! list indexing returning a Maybe
Generate.hs view
@@ -81,7 +81,7 @@  hidden :: String -> [String] hidden "Data.List.NonEmpty.Extra" = words-    "cons snoc sortOn union unionBy nubOrd nubOrdBy nubOrdOn (!?)"+    "cons snoc sortOn union unionBy nubOrd nubOrdBy nubOrdOn (!?) foldl1' repeatedly" hidden _ = []  notHidden :: String -> String -> Bool
LICENSE view
@@ -1,4 +1,4 @@-Copyright Neil Mitchell 2014-2021.+Copyright Neil Mitchell 2014-2022. All rights reserved.  Redistribution and use in source and binary forms, with or without
README.md view
@@ -15,7 +15,7 @@  * I have been using most of these functions in my packages - they have proved useful enough to be worth copying/pasting into each project. * The functions follow the spirit of the original Prelude/base libraries. I am happy to provide partial functions (e.g. `fromRight`), and functions which are specialisations of more generic functions (`whenJust`).-* Most of the functions have trivial implementations. If a beginner couldn't write the function, it probably doesn't belong here.+* Most of the functions have trivial implementations that are obvious from their name/signature. If a beginner couldn't write the function, it probably doesn't belong here. * I have defined only a few new data types or type aliases. It's a package for defining new utilities on existing types, not new types or concepts.  ## Base versions
extra.cabal view
@@ -1,13 +1,13 @@ cabal-version:      1.18 build-type:         Simple name:               extra-version:            1.7.10+version:            1.7.11 license:            BSD3 license-file:       LICENSE category:           Development author:             Neil Mitchell <ndmitchell@gmail.com> maintainer:         Neil Mitchell <ndmitchell@gmail.com>-copyright:          Neil Mitchell 2014-2021+copyright:          Neil Mitchell 2014-2022 synopsis:           Extra functions I use. description:     A library of extra functions for the standard Haskell libraries. Most functions are simple additions, filling out missing functionality. A few functions are available in later versions of GHC, but this package makes them available back to GHC 7.2.@@ -15,7 +15,7 @@     The module "Extra" documents all functions provided by this library. Modules such as "Data.List.Extra" provide extra functions over "Data.List" and also reexport "Data.List". Users are recommended to replace "Data.List" imports with "Data.List.Extra" if they need the extra functionality. homepage:           https://github.com/ndmitchell/extra#readme bug-reports:        https://github.com/ndmitchell/extra/issues-tested-with:        GHC==9.0, GHC==8.10, GHC==8.8, GHC==8.6, GHC==8.4, GHC==8.2, GHC==8.0+tested-with:        GHC==9.0, GHC==8.10, GHC==8.8, GHC==8.6  extra-doc-files:     CHANGES.txt
src/Control/Monad/Extra.hs view
@@ -30,6 +30,7 @@ -- General utilities  -- | Perform some operation on 'Just', given the field inside the 'Just'.+--   This is a specialized 'Data.Foldable.for_'. -- -- > whenJust Nothing  print == pure () -- > whenJust (Just 1) print == print 1
src/Data/List/Extra.hs view
@@ -25,13 +25,13 @@     -- * List operations     groupSort, groupSortOn, groupSortBy,     nubOrd, nubOrdBy, nubOrdOn,-    nubOn, groupOn,+    nubOn, groupOn, groupOnKey,     nubSort, nubSortBy, nubSortOn,     maximumOn, minimumOn,     sum', product',     sumOn', productOn',     disjoint, disjointOrd, disjointOrdBy, allSame, anySame,-    repeatedly, firstJust,+    repeatedly, repeatedlyNE, firstJust,     concatUnzip, concatUnzip3,     zipFrom, zipWithFrom, zipWithLongest,     replace, merge, mergeBy,@@ -48,11 +48,16 @@ import Data.Functor import Data.Foldable import Prelude+import Data.List.NonEmpty (NonEmpty ((:|)))   -- | Apply some operation repeatedly, producing an element of output --   and the remainder of the list. --+-- When the empty list is reached it is returned, so the operation+-- is /never/ applied to the empty input.+-- That fact is encoded in the type system with 'repeatedlyNE'+-- -- > \xs -> repeatedly (splitAt 3) xs  == chunksOf 3 xs -- > \xs -> repeatedly word1 (trim xs) == words xs -- > \xs -> repeatedly line1 xs == lines xs@@ -61,7 +66,17 @@ repeatedly f as = b : repeatedly f as'     where (b, as') = f as +-- | Apply some operation repeatedly, producing an element of output+--   and the remainder of the list.+--+-- Identical to 'repeatedly', but has a more precise type signature.+repeatedlyNE :: (NonEmpty a -> (b, [a])) -> [a] -> [b]+repeatedlyNE f [] = []+repeatedlyNE f (a : as) = b : repeatedlyNE f as'+    where (b, as') = f (a :| as) ++ -- | Are two lists disjoint, with no elements in common. -- -- > disjoint [1,2,3] [4,5] == True@@ -72,7 +87,7 @@ -- | /O((m+n) log m), m <= n/. Are two lists disjoint, with no elements in common. -- -- @disjointOrd@ is more strict than `disjoint`. For example, @disjointOrd@ cannot--- terminate if both lists are inifite, while `disjoint` can.+-- terminate if both lists are infinite, while `disjoint` can. -- -- > disjointOrd [1,2,3] [4,5] == True -- > disjointOrd [1,2,3] [4,1] == False@@ -411,10 +426,24 @@   -- | A version of 'group' where the equality is done on some extracted value.-groupOn :: Eq b => (a -> b) -> [a] -> [[a]]+--+-- > groupOn abs [1,-1,2] == [[1,-1], [2]]+groupOn :: Eq k => (a -> k) -> [a] -> [[a]] groupOn f = groupBy ((==) `on2` f)     -- redefine on so we avoid duplicate computation for most values.     where (.*.) `on2` f = \x -> let fx = f x in \y -> fx .*. f y+++-- | A version of 'groupOn' which pairs each group with its "key" - the+--   extracted value used for equality testing.+--+-- > groupOnKey abs [1,-1,2] == [(1, [1,-1]), (2, [2])]+groupOnKey :: Eq k => (a -> k) -> [a] -> [(k, [a])]+groupOnKey _ []     = []+groupOnKey f (x:xs) = (fx, x:yes) : groupOnKey f no+    where+        fx = f x+        (yes, no) = span (\y -> fx == f y) xs   -- | /DEPRECATED/ Use 'nubOrdOn', since this function is _O(n^2)_.
src/Data/List/NonEmpty/Extra.hs view
@@ -8,7 +8,8 @@     appendl, appendr,     sortOn, union, unionBy,     nubOrd, nubOrdBy, nubOrdOn,-    maximum1, minimum1, maximumBy1, minimumBy1, maximumOn1, minimumOn1+    maximum1, minimum1, maximumBy1, minimumBy1, maximumOn1, minimumOn1,+    foldl1', repeatedly     ) where  import           Data.Function@@ -123,3 +124,13 @@ -- | A version of 'minimum1' where the comparison is done on some extracted value. minimumOn1 :: Ord b => (a -> b) -> NonEmpty a -> a minimumOn1 f = minimumBy1 (compare `on` f)++-- | A strict variant of variant `foldl1`+foldl1' :: (a -> a -> a) -> NonEmpty a -> a+foldl1' f (x:|xs) =  List.foldl' f x xs++-- | Apply some operation repeatedly, producing an element of output+--   and the remainder of the list.+repeatedly :: (NonEmpty a -> (b, [a])) -> NonEmpty a -> NonEmpty b+repeatedly f (a :| as) = b :| List.repeatedlyNE f as'+    where (b, as') = f (a :| as)
src/Extra.hs view
@@ -23,7 +23,7 @@     writeIORef', atomicWriteIORef', atomicModifyIORef_, atomicModifyIORef'_,     -- * Data.List.Extra     -- | Extra functions available in @"Data.List.Extra"@.-    lower, upper, trim, trimStart, trimEnd, word1, line1, escapeHTML, escapeJSON, unescapeHTML, unescapeJSON, dropEnd, takeEnd, splitAtEnd, breakEnd, spanEnd, dropWhileEnd', takeWhileEnd, stripSuffix, stripInfix, stripInfixEnd, dropPrefix, dropSuffix, wordsBy, linesBy, breakOn, breakOnEnd, splitOn, split, chunksOf, headDef, lastDef, (!?), notNull, list, unsnoc, cons, snoc, drop1, dropEnd1, mconcatMap, compareLength, comparingLength, enumerate, groupSort, groupSortOn, groupSortBy, nubOrd, nubOrdBy, nubOrdOn, nubOn, groupOn, nubSort, nubSortBy, nubSortOn, maximumOn, minimumOn, sum', product', sumOn', productOn', disjoint, disjointOrd, disjointOrdBy, allSame, anySame, repeatedly, firstJust, concatUnzip, concatUnzip3, zipFrom, zipWithFrom, zipWithLongest, replace, merge, mergeBy,+    lower, upper, trim, trimStart, trimEnd, word1, line1, escapeHTML, escapeJSON, unescapeHTML, unescapeJSON, dropEnd, takeEnd, splitAtEnd, breakEnd, spanEnd, dropWhileEnd', takeWhileEnd, stripSuffix, stripInfix, stripInfixEnd, dropPrefix, dropSuffix, wordsBy, linesBy, breakOn, breakOnEnd, splitOn, split, chunksOf, headDef, lastDef, (!?), notNull, list, unsnoc, cons, snoc, drop1, dropEnd1, mconcatMap, compareLength, comparingLength, enumerate, groupSort, groupSortOn, groupSortBy, nubOrd, nubOrdBy, nubOrdOn, nubOn, groupOn, groupOnKey, nubSort, nubSortBy, nubSortOn, maximumOn, minimumOn, sum', product', sumOn', productOn', disjoint, disjointOrd, disjointOrdBy, allSame, anySame, repeatedly, repeatedlyNE, firstJust, concatUnzip, concatUnzip3, zipFrom, zipWithFrom, zipWithLongest, replace, merge, mergeBy,     -- * Data.List.NonEmpty.Extra     -- | Extra functions available in @"Data.List.NonEmpty.Extra"@.     (|:), (|>), appendl, appendr, maximum1, minimum1, maximumBy1, minimumBy1, maximumOn1, minimumOn1,@@ -59,7 +59,7 @@ import Data.Either.Extra import Data.IORef.Extra import Data.List.Extra-import Data.List.NonEmpty.Extra hiding (cons, snoc, sortOn, union, unionBy, nubOrd, nubOrdBy, nubOrdOn, (!?))+import Data.List.NonEmpty.Extra hiding (cons, snoc, sortOn, union, unionBy, nubOrd, nubOrdBy, nubOrdOn, (!?), foldl1', repeatedly) import Data.Tuple.Extra import Data.Version.Extra import Numeric.Extra
test/Test.hs view
@@ -16,5 +16,6 @@  main :: IO () main = runTests $ do+    testSetup     tests     testCustom
test/TestCustom.hs view
@@ -1,5 +1,5 @@ -module TestCustom(testCustom) where+module TestCustom(testSetup, testCustom) where  import Control.Concurrent.Extra import Control.Monad@@ -9,6 +9,14 @@ import Data.List.Extra as X  +-- | Test that the basic test mechanisms work+testSetup :: IO ()+testSetup = do+    testGen "withTempFile" $ withTempFile (`writeFile` "") == pure ()+    testGen "captureOutput" $ captureOutput (print 1) == pure ("1\n", ())+++-- | Custom written tests testCustom :: IO () testCustom = do     -- check that Extra really does export these things
test/TestGen.hs view
@@ -171,6 +171,8 @@     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 "groupOn abs [1,-1,2] == [[1,-1], [2]]" $ groupOn abs [1,-1,2] == [[1,-1], [2]]+    testGen "groupOnKey abs [1,-1,2] == [(1, [1,-1]), (2, [2])]" $ groupOnKey abs [1,-1,2] == [(1, [1,-1]), (2, [2])]     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 []
test/TestUtil.hs view
@@ -83,8 +83,8 @@ -- So we print out full information on failure instance (Show a, Eq a) => Eq (IO a) where     a == b = unsafePerformIO $ do-        a <- try_ $ captureOutput a-        b <- try_ $ captureOutput b+        a <- captureOutput $ try_ a+        b <- captureOutput $ try_ b         if a == b then pure True else             error $ show ("IO values not equal", a, b)