Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package ghc-extra for openSUSE:Factory checked in at 2023-04-04 21:19:56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ghc-extra (Old) and /work/SRC/openSUSE:Factory/.ghc-extra.new.19717 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ghc-extra" Tue Apr 4 21:19:56 2023 rev:33 rq:1075869 version:1.7.12 Changes: -------- --- /work/SRC/openSUSE:Factory/ghc-extra/ghc-extra.changes 2021-09-10 23:41:21.314562190 +0200 +++ /work/SRC/openSUSE:Factory/.ghc-extra.new.19717/ghc-extra.changes 2023-04-04 21:20:08.721085181 +0200 @@ -1,0 +2,23 @@ +Thu Mar 30 17:06:44 UTC 2023 - Peter Simons <psim...@suse.com> + +- Updated spec file to conform with ghc-rpm-macros-2.5.2. + +------------------------------------------------------------------- +Fri Sep 2 11:34:48 UTC 2022 - Peter Simons <psim...@suse.com> + +- Update extra to version 1.7.12. + 1.7.12, released 2022-09-02 + #98, make both lazy in its argument + #98, make first3,second3,third3 lazy in their argument + #98, make firstM,secondM lazy in their argument + #86, add notNull for Foldable + 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 + #80, add strict Var functions modifyVar', modifyVar_', writeVar' + +------------------------------------------------------------------- Old: ---- extra-1.7.9.tar.gz New: ---- extra-1.7.12.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ghc-extra.spec ++++++ --- /var/tmp/diff_new_pack.qlCnUv/_old 2023-04-04 21:20:09.305088905 +0200 +++ /var/tmp/diff_new_pack.qlCnUv/_new 2023-04-04 21:20:09.309088930 +0200 @@ -1,7 +1,7 @@ # # spec file for package ghc-extra # -# Copyright (c) 2021 SUSE LLC +# Copyright (c) 2023 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,26 +17,37 @@ %global pkg_name extra +%global pkgver %{pkg_name}-%{version} %bcond_with tests Name: ghc-%{pkg_name} -Version: 1.7.9 +Version: 1.7.12 Release: 0 Summary: Extra functions I use License: BSD-3-Clause URL: https://hackage.haskell.org/package/%{pkg_name} Source0: https://hackage.haskell.org/package/%{pkg_name}-%{version}/%{pkg_name}-%{version}.tar.gz BuildRequires: ghc-Cabal-devel +BuildRequires: ghc-base-devel +BuildRequires: ghc-base-prof BuildRequires: ghc-clock-devel +BuildRequires: ghc-clock-prof BuildRequires: ghc-directory-devel +BuildRequires: ghc-directory-prof BuildRequires: ghc-filepath-devel +BuildRequires: ghc-filepath-prof BuildRequires: ghc-process-devel +BuildRequires: ghc-process-prof BuildRequires: ghc-rpm-macros BuildRequires: ghc-time-devel +BuildRequires: ghc-time-prof BuildRequires: ghc-unix-devel +BuildRequires: ghc-unix-prof ExcludeArch: %{ix86} %if %{with tests} BuildRequires: ghc-QuickCheck-devel +BuildRequires: ghc-QuickCheck-prof BuildRequires: ghc-quickcheck-instances-devel +BuildRequires: ghc-quickcheck-instances-prof %endif %description @@ -60,6 +71,22 @@ %description devel This package provides the Haskell %{pkg_name} library development files. +%package -n ghc-%{pkg_name}-doc +Summary: Haskell %{pkg_name} library documentation +Requires: ghc-filesystem +BuildArch: noarch + +%description -n ghc-%{pkg_name}-doc +This package provides the Haskell %{pkg_name} library documentation. + +%package -n ghc-%{pkg_name}-prof +Summary: Haskell %{pkg_name} profiling library +Requires: ghc-%{pkg_name}-devel = %{version}-%{release} +Supplements: (ghc-%{pkg_name}-devel and ghc-prof) + +%description -n ghc-%{pkg_name}-prof +This package provides the Haskell %{pkg_name} profiling library. + %prep %autosetup -n %{pkg_name}-%{version} @@ -84,4 +111,9 @@ %files devel -f %{name}-devel.files %doc CHANGES.txt README.md +%files -n ghc-%{pkg_name}-doc -f ghc-%{pkg_name}-doc.files +%license LICENSE + +%files -n ghc-%{pkg_name}-prof -f ghc-%{pkg_name}-prof.files + %changelog ++++++ extra-1.7.9.tar.gz -> extra-1.7.12.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/extra-1.7.9/CHANGES.txt new/extra-1.7.12/CHANGES.txt --- old/extra-1.7.9/CHANGES.txt 2020-12-19 17:13:47.000000000 +0100 +++ new/extra-1.7.12/CHANGES.txt 2001-09-09 03:46:40.000000000 +0200 @@ -1,5 +1,18 @@ Changelog for Extra +1.7.12, released 2022-09-02 + #98, make both lazy in its argument + #98, make first3,second3,third3 lazy in their argument + #98, make firstM,secondM lazy in their argument + #86, add notNull for Foldable +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 + #80, add strict Var functions modifyVar', modifyVar_', writeVar' 1.7.9, released 2020-12-19 #72, add pureIf #73, make takeEnd, dropEnd, splitAtEnd: return immediately if i <= 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/extra-1.7.9/Generate.hs new/extra-1.7.12/Generate.hs --- old/extra-1.7.9/Generate.hs 2020-12-15 21:36:53.000000000 +0100 +++ new/extra-1.7.12/Generate.hs 2001-09-09 03:46:40.000000000 +0200 @@ -1,5 +1,5 @@ -- This module generates the files src/Extra.hs and test/TestGen.hs. --- Either call "runhaskell Generate" or start "ghci" and use ":generate". +-- Either call "runghc Generate" or start "ghci" and use ":generate". module Generate(main) where @@ -24,7 +24,7 @@ let funcs = filter validIdentifier $ takeWhile (/= "where") $ words $ replace "," " " $ drop1 $ dropWhile (/= '(') $ unlines $ filter (\x -> not $ any (`isPrefixOf` trim x) ["--","#"]) $ lines src - let tests = mapMaybe (stripPrefix "-- > ") $ lines src + let tests = if mod `elem` excludeTests then [] else mapMaybe (stripPrefix "-- > ") $ lines src pure (mod, funcs, tests) writeFileBinaryChanged "src/Extra.hs" $ unlines $ ["-- GENERATED CODE - DO NOT MODIFY" @@ -49,8 +49,6 @@ ,"{-# LANGUAGE ExtendedDefaultRules, ScopedTypeVariables, TypeApplications, ViewPatterns #-}" ,"module TestGen(tests) where" ,"import TestUtil" - ,"import qualified Data.List" - ,"import qualified Data.List.NonEmpty.Extra" ,"import qualified Data.Ord" ,"import Test.QuickCheck.Instances.Semigroup ()" ,"default(Maybe Bool,Int,Double,Maybe (Maybe Bool),Maybe (Maybe Char))" @@ -71,11 +69,19 @@ writeFileBinary file x exclude :: [String] -exclude = ["Data.Foldable.Extra"] -- because all their imports clash +exclude = + ["Data.Foldable.Extra" -- because all their imports clash + ] + +excludeTests :: [String] +-- FIXME: Should probably generate these in another module +excludeTests = + ["Data.List.NonEmpty.Extra" -- because !? clashes and is tested + ] 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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/extra-1.7.9/LICENSE new/extra-1.7.12/LICENSE --- old/extra-1.7.9/LICENSE 2020-02-10 14:40:40.000000000 +0100 +++ new/extra-1.7.12/LICENSE 2001-09-09 03:46:40.000000000 +0200 @@ -1,4 +1,4 @@ -Copyright Neil Mitchell 2014-2020. +Copyright Neil Mitchell 2014-2022. All rights reserved. Redistribution and use in source and binary forms, with or without diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/extra-1.7.9/README.md new/extra-1.7.12/README.md --- old/extra-1.7.9/README.md 2020-11-24 11:02:29.000000000 +0100 +++ new/extra-1.7.12/README.md 2001-09-09 03:46:40.000000000 +0200 @@ -1,4 +1,4 @@ -# Extra [](https://hackage.haskell.org/package/extra) [](https://www.stackage.org/package/extra) [](https://github.com/ndmitchell/extra/actions) +# Extra [](https://hackage.haskell.org/package/extra) [](https://www.stackage.org/package/extra) [](https://github.com/ndmitchell/extra/actions) 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.10. A few examples: @@ -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 @@ -24,4 +24,4 @@ ## Contributing -My general contribution preferences are [available here](https://github.com/ndmitchell/neil#contributions). In addition, this repo contains some generated code which is checked in, namely [src/Extra.hs](src/Extra.hs) and [test/TestGen.hs](test/TestGen.hs). You can generate those files by either running `runhaskell Generate.hs` or `ghci` (which uses the [`.ghci` file](.ghci)) and typing `:generate`. All PR's should contain regenerated versions of those files. +My general contribution preferences are [available here](https://github.com/ndmitchell/neil#contributions). In addition, this repo contains some generated code which is checked in, namely [src/Extra.hs](src/Extra.hs) and [test/TestGen.hs](test/TestGen.hs). You can generate those files by either running `runghc Generate.hs` or `ghci` (which uses the [`.ghci` file](.ghci)) and typing `:generate`. All PR's should contain regenerated versions of those files. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/extra-1.7.9/extra.cabal new/extra-1.7.12/extra.cabal --- old/extra-1.7.9/extra.cabal 2020-12-19 17:13:58.000000000 +0100 +++ new/extra-1.7.12/extra.cabal 2001-09-09 03:46:40.000000000 +0200 @@ -1,13 +1,13 @@ -cabal-version: >= 1.18 +cabal-version: 1.18 build-type: Simple name: extra -version: 1.7.9 +version: 1.7.12 license: BSD3 license-file: LICENSE category: Development author: Neil Mitchell <ndmitch...@gmail.com> maintainer: Neil Mitchell <ndmitch...@gmail.com> -copyright: Neil Mitchell 2014-2020 +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==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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/extra-1.7.9/src/Control/Concurrent/Extra.hs new/extra-1.7.12/src/Control/Concurrent/Extra.hs --- old/extra-1.7.9/src/Control/Concurrent/Extra.hs 2020-11-23 09:59:51.000000000 +0100 +++ new/extra-1.7.12/src/Control/Concurrent/Extra.hs 2001-09-09 03:46:40.000000000 +0200 @@ -18,7 +18,11 @@ -- * Lock Lock, newLock, withLock, withLockTry, -- * Var - Var, newVar, readVar, writeVar, modifyVar, modifyVar_, withVar, + Var, newVar, readVar, + writeVar, writeVar', + modifyVar, modifyVar', + modifyVar_, modifyVar_', + withVar, -- * Barrier Barrier, newBarrier, signalBarrier, waitBarrier, waitBarrierMaybe, ) where @@ -30,6 +34,7 @@ import Data.Either.Extra import Data.Functor import Prelude +import Data.Tuple.Extra (dupe) -- | On GHC 7.6 and above with the @-threaded@ flag, brackets a call to 'setNumCapabilities'. @@ -152,14 +157,34 @@ writeVar :: Var a -> a -> IO () writeVar v x = modifyVar_ v $ const $ pure x +-- | Strict variant of 'writeVar' +writeVar' :: Var a -> a -> IO () +writeVar' v x = modifyVar_' v $ const $ pure x + -- | Modify a 'Var' producing a new value and a return result. modifyVar :: Var a -> (a -> IO (a, b)) -> IO b modifyVar (Var x) f = modifyMVar x f +-- | Strict variant of 'modifyVar'' +modifyVar' :: Var a -> (a -> IO (a, b)) -> IO b +modifyVar' x f = do + (newContents, res) <- modifyVar x $ \v -> do + (newContents, res) <- f v + pure (newContents, (newContents, res)) + evaluate newContents + pure res + -- | Modify a 'Var', a restricted version of 'modifyVar'. modifyVar_ :: Var a -> (a -> IO a) -> IO () modifyVar_ (Var x) f = modifyMVar_ x f +-- | Strict variant of 'modifyVar_' +modifyVar_' :: Var a -> (a -> IO a) -> IO () +modifyVar_' x f = do + newContents <- modifyVar x (fmap dupe . f) + _ <- evaluate newContents + pure () + -- | Perform some operation using the value in the 'Var', -- a restricted version of 'modifyVar'. withVar :: Var a -> (a -> IO b) -> IO b diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/extra-1.7.9/src/Control/Exception/Extra.hs new/extra-1.7.12/src/Control/Exception/Extra.hs --- old/extra-1.7.9/src/Control/Exception/Extra.hs 2020-08-12 10:13:06.000000000 +0200 +++ new/extra-1.7.12/src/Control/Exception/Extra.hs 2001-09-09 03:46:40.000000000 +0200 @@ -13,7 +13,7 @@ retry, retryBool, errorWithoutStackTrace, showException, stringException, - errorIO, + errorIO, assertIO, -- * Exception catching/ignoring ignore, catch_, handle_, try_, @@ -85,6 +85,13 @@ withFrozenCallStack = id #endif +-- | An 'IO' action that when evaluated calls 'assert' in the 'IO' monad, which throws an 'AssertionFailed' exception if the argument is 'False'. +-- With optimizations enabled (and @-fgnore-asserts@) this function ignores its argument and does nothing. +-- +-- > catch (assertIO True >> pure 1) (\(x :: AssertionFailed) -> pure 2) == pure 1 +-- > seq (assertIO False) (print 1) == print 1 +assertIO :: Partial => Bool -> IO () +assertIO x = withFrozenCallStack $ evaluate $ assert x () -- | Retry an operation at most /n/ times (/n/ must be positive). -- If the operation fails the /n/th time it will throw that final exception. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/extra-1.7.9/src/Control/Monad/Extra.hs new/extra-1.7.12/src/Control/Monad/Extra.hs --- old/extra-1.7.9/src/Control/Monad/Extra.hs 2020-12-15 21:36:15.000000000 +0100 +++ new/extra-1.7.12/src/Control/Monad/Extra.hs 2001-09-09 03:46:40.000000000 +0200 @@ -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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/extra-1.7.9/src/Data/Foldable/Extra.hs new/extra-1.7.12/src/Data/Foldable/Extra.hs --- old/extra-1.7.9/src/Data/Foldable/Extra.hs 2020-09-12 14:10:14.000000000 +0200 +++ new/extra-1.7.12/src/Data/Foldable/Extra.hs 2001-09-09 03:46:40.000000000 +0200 @@ -1,5 +1,6 @@ module Data.Foldable.Extra ( module Data.Foldable + , notNull , sum' , product' , sumOn' @@ -15,6 +16,10 @@ import Data.Foldable import qualified Control.Monad.Extra as MX +-- | Composition of 'not' and 'null' +notNull :: Foldable f => f a -> Bool +notNull = not . null + -- | A generalization of 'Data.List.Extra.sum'' to 'Foldable' instances. sum' :: (Foldable f, Num a) => f a -> a sum' = foldl' (+) 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/extra-1.7.9/src/Data/List/Extra.hs new/extra-1.7.12/src/Data/List/Extra.hs --- old/extra-1.7.9/src/Data/List/Extra.hs 2020-12-15 21:36:15.000000000 +0100 +++ new/extra-1.7.12/src/Data/List/Extra.hs 2001-09-09 03:46:40.000000000 +0200 @@ -18,20 +18,20 @@ wordsBy, linesBy, breakOn, breakOnEnd, splitOn, split, chunksOf, -- * Basics - headDef, lastDef, notNull, list, unsnoc, cons, snoc, + headDef, lastDef, (!?), notNull, list, unsnoc, cons, snoc, drop1, dropEnd1, mconcatMap, compareLength, comparingLength, -- * Enum operations enumerate, -- * 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,6 +66,16 @@ 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. -- @@ -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 @@ -141,6 +156,19 @@ lastDef d xs = foldl (\_ x -> x) d xs -- I know this looks weird, but apparently this is the fastest way to do this: https://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.List.html#last {-# INLINE lastDef #-} +-- | A total variant of the list index function `(!!)`. +-- +-- > [2,3,4] !? 1 == Just 3 +-- > [2,3,4] !? (-1) == Nothing +-- > [] !? 0 == Nothing +(!?) :: [a] -> Int -> Maybe a +xs !? n + | n < 0 = Nothing + -- Definition adapted from GHC.List + | otherwise = foldr (\x r k -> case k of + 0 -> Just x + _ -> r (k-1)) (const Nothing) xs n +{-# INLINABLE (!?) #-} -- | A composition of 'not' and 'null'. -- @@ -237,7 +265,7 @@ -- | 'zip' against an enumeration. --- Never truncates the output - raises an error if the enumeration runs out. +-- Truncates the output if the enumeration runs out. -- -- > \i xs -> zip [i..] xs == zipFrom i xs -- > zipFrom False [1..3] == [(False,1),(True, 2)] @@ -245,7 +273,7 @@ zipFrom = zipWithFrom (,) -- | 'zipFrom' generalised to any combining operation. --- Never truncates the output - raises an error if the enumeration runs out. +-- Truncates the output if the enumeration runs out. -- -- > \i xs -> zipWithFrom (,) i xs == zipFrom i xs zipWithFrom :: Enum a => (a -> b -> c) -> a -> [b] -> [c] @@ -398,12 +426,26 @@ -- | 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)_. -- -- A version of 'nub' where the equality is done on some extracted value. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/extra-1.7.9/src/Data/List/NonEmpty/Extra.hs new/extra-1.7.12/src/Data/List/NonEmpty/Extra.hs --- old/extra-1.7.9/src/Data/List/NonEmpty/Extra.hs 2020-03-02 10:33:57.000000000 +0100 +++ new/extra-1.7.12/src/Data/List/NonEmpty/Extra.hs 2001-09-09 03:46:40.000000000 +0200 @@ -4,11 +4,12 @@ -- also exports the existing "Data.List.NonEmpty" functions. module Data.List.NonEmpty.Extra( module Data.List.NonEmpty, - (|:), (|>), snoc, + (|:), (|>), snoc, (!?), 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 @@ -37,6 +38,18 @@ (|:) :: [a] -> a -> NonEmpty a (|:) xs x = foldr cons (pure x) xs +-- | A total variant of the list index function `(!?)`. +-- +-- > (2 :| [3,4]) !? 1 == Just 3 +-- > (2 :| [3,4]) !? (-1) == Nothing +-- > (1 :| []) !? 1 == Nothing +(!?) :: NonEmpty a -> Int -> Maybe a +(!?) ~(x :| xs) n + | n == 0 = Just x + | n > 0 = xs List.!? (n - 1) + | otherwise = Nothing +infixl 9 !? + -- | Append a list to a non-empty list. -- -- > appendl (1 :| [2,3]) [4,5] == 1 :| [2,3,4,5] @@ -111,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) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/extra-1.7.9/src/Data/Tuple/Extra.hs new/extra-1.7.12/src/Data/Tuple/Extra.hs --- old/extra-1.7.9/src/Data/Tuple/Extra.hs 2020-06-06 17:55:42.000000000 +0200 +++ new/extra-1.7.12/src/Data/Tuple/Extra.hs 2001-09-09 03:46:40.000000000 +0200 @@ -38,13 +38,13 @@ -- -- > firstM (\x -> [x-1, x+1]) (1,"test") == [(0,"test"),(2,"test")] firstM :: Functor m => (a -> m a') -> (a, b) -> m (a', b) -firstM f (a,b) = (,b) <$> f a +firstM f ~(a,b) = (,b) <$> f a -- | Update the second component of a pair. -- -- > secondM (\x -> [reverse x, x]) (1,"test") == [(1,"tset"),(1,"test")] secondM :: Functor m => (b -> m b') -> (a, b) -> m (a, b') -secondM f (a,b) = (a,) <$> f b +secondM f ~(a,b) = (a,) <$> f b -- | Given two functions, apply one to the first component and one to the second. -- A specialised version of 'Control.Arrow.***'. @@ -70,7 +70,7 @@ -- -- > both succ (1,2) == (2,3) both :: (a -> b) -> (a, a) -> (b, b) -both f (x,y) = (f x, f y) +both f ~(x,y) = (f x, f y) -- | Extract the 'fst' of a triple. fst3 :: (a,b,c) -> a @@ -97,16 +97,16 @@ -- -- > first3 succ (1,1,1) == (2,1,1) first3 :: (a -> a') -> (a, b, c) -> (a', b, c) -first3 f (a,b,c) = (f a,b,c) +first3 f ~(a,b,c) = (f a,b,c) -- | Update the second component of a triple. -- -- > second3 succ (1,1,1) == (1,2,1) second3 :: (b -> b') -> (a, b, c) -> (a, b', c) -second3 f (a,b,c) = (a,f b,c) +second3 f ~(a,b,c) = (a,f b,c) -- | Update the third component of a triple. -- -- > third3 succ (1,1,1) == (1,1,2) third3 :: (c -> c') -> (a, b, c) -> (a, b, c') -third3 f (a,b,c) = (a,b,f c) +third3 f ~(a,b,c) = (a,b,f c) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/extra-1.7.9/src/Extra.hs new/extra-1.7.12/src/Extra.hs --- old/extra-1.7.9/src/Extra.hs 2020-12-15 21:36:15.000000000 +0100 +++ new/extra-1.7.12/src/Extra.hs 2001-09-09 03:46:40.000000000 +0200 @@ -8,10 +8,10 @@ module Extra {-# DEPRECATED "This module is provided as documentation of all new functions, you should import the more specific modules directly." #-} ( -- * Control.Concurrent.Extra -- | Extra functions available in @"Control.Concurrent.Extra"@. - withNumCapabilities, once, onceFork, Lock, newLock, withLock, withLockTry, Var, newVar, readVar, writeVar, modifyVar, modifyVar_, withVar, Barrier, newBarrier, signalBarrier, waitBarrier, waitBarrierMaybe, + withNumCapabilities, once, onceFork, Lock, newLock, withLock, withLockTry, Var, newVar, readVar, writeVar, writeVar', modifyVar, modifyVar', modifyVar_, modifyVar_', withVar, Barrier, newBarrier, signalBarrier, waitBarrier, waitBarrierMaybe, -- * Control.Exception.Extra -- | Extra functions available in @"Control.Exception.Extra"@. - Partial, retry, retryBool, errorWithoutStackTrace, showException, stringException, errorIO, ignore, catch_, handle_, try_, catchJust_, handleJust_, tryJust_, catchBool, handleBool, tryBool, + Partial, retry, retryBool, errorWithoutStackTrace, showException, stringException, errorIO, assertIO, ignore, catch_, handle_, try_, catchJust_, handleJust_, tryJust_, catchBool, handleBool, tryBool, -- * Control.Monad.Extra -- | Extra functions available in @"Control.Monad.Extra"@. whenJust, whenJustM, pureIf, whenMaybe, whenMaybeM, unit, maybeM, fromMaybeM, eitherM, loop, loopM, whileM, whileJustM, untilJustM, partitionM, concatMapM, concatForM, mconcatMapM, mapMaybeM, findM, firstJustM, fold1M, fold1M_, whenM, unlessM, ifM, notM, (||^), (&&^), orM, andM, anyM, allM, @@ -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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/extra-1.7.9/test/Test.hs new/extra-1.7.12/test/Test.hs --- old/extra-1.7.9/test/Test.hs 2016-04-29 11:23:56.000000000 +0200 +++ new/extra-1.7.12/test/Test.hs 2001-09-09 03:46:40.000000000 +0200 @@ -16,5 +16,6 @@ main :: IO () main = runTests $ do + testSetup tests testCustom diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/extra-1.7.9/test/TestCustom.hs new/extra-1.7.12/test/TestCustom.hs --- old/extra-1.7.9/test/TestCustom.hs 2020-05-25 14:28:20.000000000 +0200 +++ new/extra-1.7.12/test/TestCustom.hs 2001-09-09 03:46:40.000000000 +0200 @@ -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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/extra-1.7.9/test/TestGen.hs new/extra-1.7.12/test/TestGen.hs --- old/extra-1.7.9/test/TestGen.hs 2020-12-15 21:37:00.000000000 +0100 +++ new/extra-1.7.12/test/TestGen.hs 2001-09-09 03:46:40.000000000 +0200 @@ -4,8 +4,6 @@ {-# LANGUAGE ExtendedDefaultRules, ScopedTypeVariables, TypeApplications, ViewPatterns #-} module TestGen(tests) where import TestUtil -import qualified Data.List -import qualified Data.List.NonEmpty.Extra import qualified Data.Ord import Test.QuickCheck.Instances.Semigroup () default(Maybe Bool,Int,Double,Maybe (Maybe Bool),Maybe (Maybe Char)) @@ -26,6 +24,8 @@ testGen "ignore (fail \"die\") == pure ()" $ ignore (fail "die") == pure () testGen "catch (errorIO \"Hello\") (\\(ErrorCall x) -> pure x) == pure \"Hello\"" $ catch (errorIO "Hello") (\(ErrorCall x) -> pure x) == pure "Hello" testGen "seq (errorIO \"foo\") (print 1) == print 1" $ seq (errorIO "foo") (print 1) == print 1 + testGen "catch (assertIO True >> pure 1) (\\(x :: AssertionFailed) -> pure 2) == pure 1" $ catch (assertIO True >> pure 1) (\(x :: AssertionFailed) -> pure 2) == pure 1 + testGen "seq (assertIO False) (print 1) == print 1" $ seq (assertIO False) (print 1) == print 1 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 == pure ()" $ whenJust Nothing print == pure () @@ -107,6 +107,9 @@ testGen "lastDef 1 [] == 1" $ lastDef 1 [] == 1 testGen "lastDef 1 [2,3,4] == 4" $ lastDef 1 [2,3,4] == 4 testGen "\\x xs -> lastDef x xs == last (x:xs)" $ \x xs -> lastDef x xs == last (x:xs) + testGen "[2,3,4] !? 1 == Just 3" $ [2,3,4] !? 1 == Just 3 + testGen "[2,3,4] !? (-1) == Nothing" $ [2,3,4] !? (-1) == Nothing + testGen "[] !? 0 == Nothing" $ [] !? 0 == Nothing testGen "notNull [] == False" $ notNull [] == False testGen "notNull [1] == True" $ notNull [1] == True testGen "\\xs -> notNull xs == not (null xs)" $ \xs -> notNull xs == not (null xs) @@ -168,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 [] @@ -266,15 +271,6 @@ testGen "\\(xs :: [Int]) (ys :: [Int]) -> comparingLength xs ys == Data.Ord.comparing length xs ys" $ \(xs :: [Int]) (ys :: [Int]) -> comparingLength xs ys == Data.Ord.comparing length xs ys testGen "comparingLength [1,2] (1:2:3:undefined) == LT" $ comparingLength [1,2] (1:2:3:undefined) == LT testGen "comparingLength (1:2:3:undefined) [1,2] == GT" $ comparingLength (1:2:3:undefined) [1,2] == GT - testGen "(1 :| [2,3]) |> 4 |> 5 == 1 :| [2,3,4,5]" $ (1 :| [2,3]) |> 4 |> 5 == 1 :| [2,3,4,5] - testGen "[1,2,3] |: 4 |> 5 == 1 :| [2,3,4,5]" $ [1,2,3] |: 4 |> 5 == 1 :| [2,3,4,5] - testGen "appendl (1 :| [2,3]) [4,5] == 1 :| [2,3,4,5]" $ appendl (1 :| [2,3]) [4,5] == 1 :| [2,3,4,5] - testGen "appendr [1,2,3] (4 :| [5]) == 1 :| [2,3,4,5]" $ appendr [1,2,3] (4 :| [5]) == 1 :| [2,3,4,5] - testGen "(1 :| [3, 5, 3]) `union` (4 :| [5, 3, 5, 2]) == 1 :| [3, 5, 3, 4, 2]" $ (1 :| [3, 5, 3]) `union` (4 :| [5, 3, 5, 2]) == 1 :| [3, 5, 3, 4, 2] - testGen "Data.List.NonEmpty.Extra.nubOrd (1 :| [2, 3, 3, 4, 1, 2]) == 1 :| [2, 3, 4]" $ Data.List.NonEmpty.Extra.nubOrd (1 :| [2, 3, 3, 4, 1, 2]) == 1 :| [2, 3, 4] - testGen "\\xs -> Data.List.NonEmpty.Extra.nubOrd xs == Data.List.NonEmpty.Extra.nub xs" $ \xs -> Data.List.NonEmpty.Extra.nubOrd xs == Data.List.NonEmpty.Extra.nub xs - testGen "Data.List.NonEmpty.Extra.nubOrdBy (compare `on` Data.List.length) (\"a\" :| [\"test\",\"of\",\"this\"]) == \"a\" :| [\"test\",\"of\"]" $ Data.List.NonEmpty.Extra.nubOrdBy (compare `on` Data.List.length) ("a" :| ["test","of","this"]) == "a" :| ["test","of"] - testGen "Data.List.NonEmpty.Extra.nubOrdOn Data.List.length (\"a\" :| [\"test\",\"of\",\"this\"]) == \"a\" :| [\"test\",\"of\"]" $ Data.List.NonEmpty.Extra.nubOrdOn Data.List.length ("a" :| ["test","of","this"]) == "a" :| ["test","of"] testGen "first succ (1,\"test\") == (2,\"test\")" $ first succ (1,"test") == (2,"test") testGen "second reverse (1,\"test\") == (1,\"tset\")" $ second reverse (1,"test") == (1,"tset") testGen "firstM (\\x -> [x-1, x+1]) (1,\"test\") == [(0,\"test\"),(2,\"test\")]" $ firstM (\x -> [x-1, x+1]) (1,"test") == [(0,"test"),(2,"test")] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/extra-1.7.9/test/TestUtil.hs new/extra-1.7.12/test/TestUtil.hs --- old/extra-1.7.9/test/TestUtil.hs 2020-12-15 21:36:15.000000000 +0100 +++ new/extra-1.7.12/test/TestUtil.hs 2001-09-09 03:46:40.000000000 +0200 @@ -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)