Hello community, here is the log from the commit of package ghc-utility-ht for openSUSE:Factory checked in at 2017-01-31 12:40:20 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ghc-utility-ht (Old) and /work/SRC/openSUSE:Factory/.ghc-utility-ht.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ghc-utility-ht" Changes: -------- --- /work/SRC/openSUSE:Factory/ghc-utility-ht/ghc-utility-ht.changes 2017-01-18 21:38:21.561838033 +0100 +++ /work/SRC/openSUSE:Factory/.ghc-utility-ht.new/ghc-utility-ht.changes 2017-02-03 17:40:27.641265797 +0100 @@ -1,0 +2,5 @@ +Thu Sep 15 06:35:12 UTC 2016 - psim...@suse.com + +- Update to version 0.0.12 revision 0 with cabal2obs. + +------------------------------------------------------------------- Old: ---- utility-ht-0.0.11.tar.gz New: ---- utility-ht-0.0.12.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ghc-utility-ht.spec ++++++ --- /var/tmp/diff_new_pack.56rb2D/_old 2017-02-03 17:40:27.965219944 +0100 +++ /var/tmp/diff_new_pack.56rb2D/_new 2017-02-03 17:40:27.965219944 +0100 @@ -19,21 +19,19 @@ %global pkg_name utility-ht %bcond_with tests Name: ghc-%{pkg_name} -Version: 0.0.11 +Version: 0.0.12 Release: 0 Summary: Various small helper functions for Lists, Maybes, Tuples, Functions License: BSD-3-Clause -Group: System/Libraries +Group: Development/Languages/Other 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-rpm-macros BuildRoot: %{_tmppath}/%{name}-%{version}-build -# Begin cabal-rpm deps: %if %{with tests} BuildRequires: ghc-QuickCheck-devel %endif -# End cabal-rpm deps %description Various small helper functions for Lists, Maybes, Tuples, Functions. @@ -64,20 +62,14 @@ %prep %setup -q -n %{pkg_name}-%{version} - %build %ghc_lib_build - %install %ghc_lib_install - %check -%if %{with tests} -%{cabal} test -%endif - +%cabal_test %post devel %ghc_pkg_recache ++++++ utility-ht-0.0.11.tar.gz -> utility-ht-0.0.12.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/utility-ht-0.0.11/src/Control/Applicative/HT.hs new/utility-ht-0.0.12/src/Control/Applicative/HT.hs --- old/utility-ht-0.0.11/src/Control/Applicative/HT.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/utility-ht-0.0.12/src/Control/Applicative/HT.hs 2016-09-01 19:19:05.000000000 +0200 @@ -0,0 +1,31 @@ +module Control.Applicative.HT where + +import qualified Data.Tuple.HT as Tuple + +import Control.Applicative (Applicative, liftA2, liftA3, (<$>), (<*>), ) + +mapPair :: (Applicative f) => (a -> f c, b -> f d) -> (a,b) -> f (c,d) +mapPair fg = uncurry (liftA2 (,)) . Tuple.mapPair fg + +mapTriple :: + (Applicative m) => (a -> m d, b -> m e, c -> m f) -> (a,b,c) -> m (d,e,f) +mapTriple fgh = Tuple.uncurry3 (liftA3 (,,)) . Tuple.mapTriple fgh + + +{-# INLINE liftA4 #-} +liftA4 :: Applicative f => + (a -> b -> c -> d -> e) -> + f a -> f b -> f c -> f d -> f e +liftA4 f a b c d = f <$> a <*> b <*> c <*> d + +{-# INLINE liftA5 #-} +liftA5 :: Applicative f => + (a -> b -> c -> d -> e -> g) -> + f a -> f b -> f c -> f d -> f e -> f g +liftA5 f a b c d e = f <$> a <*> b <*> c <*> d <*> e + +{-# INLINE liftA6 #-} +liftA6 :: Applicative f => + (a -> b -> c -> d -> e -> g -> h) -> + f a -> f b -> f c -> f d -> f e -> f g -> f h +liftA6 f a b c d e g = f <$> a <*> b <*> c <*> d <*> e <*> g diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/utility-ht-0.0.11/src/Control/Functor/HT.hs new/utility-ht-0.0.12/src/Control/Functor/HT.hs --- old/utility-ht-0.0.11/src/Control/Functor/HT.hs 2015-08-19 15:11:14.000000000 +0200 +++ new/utility-ht-0.0.12/src/Control/Functor/HT.hs 2016-09-01 19:19:05.000000000 +0200 @@ -28,6 +28,24 @@ unzip3 :: Functor f => f (a, b, c) -> (f a, f b, f c) unzip3 x = (fmap fst3 x, fmap snd3 x, fmap thd3 x) + +mapFst :: Functor f => (a -> f c) -> (a, b) -> f (c, b) +mapFst f ~(a,b) = fmap (flip (,) b) $ f a + +mapSnd :: Functor f => (b -> f c) -> (a, b) -> f (a, c) +mapSnd f ~(a,b) = fmap ((,) a) $ f b + + +mapFst3 :: Functor f => (a -> f d) -> (a,b,c) -> f (d,b,c) +mapFst3 f ~(a,b,c) = fmap (\x -> (x,b,c)) $ f a + +mapSnd3 :: Functor f => (b -> f d) -> (a,b,c) -> f (a,d,c) +mapSnd3 f ~(a,b,c) = fmap (\x -> (a,x,c)) $ f b + +mapThd3 :: Functor f => (c -> f d) -> (a,b,c) -> f (a,b,d) +mapThd3 f ~(a,b,c) = fmap ((,,) a b) $ f c + + {- | Generalization of 'Data.List.HT.outerProduct'. -} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/utility-ht-0.0.11/src/Control/Monad/HT.hs new/utility-ht-0.0.12/src/Control/Monad/HT.hs --- old/utility-ht-0.0.11/src/Control/Monad/HT.hs 2015-08-19 15:11:14.000000000 +0200 +++ new/utility-ht-0.0.12/src/Control/Monad/HT.hs 2016-09-01 19:19:05.000000000 +0200 @@ -45,6 +45,15 @@ in aux m {- | +I think this makes only sense in a lazy monad +like @Trans.State.Lazy@ or @IO.Lazy@. +-} +iterate :: Monad m => (a -> m a) -> a -> m [a] +iterate f = + let go x = lift (x:) $ go =<< f x + in go + +{- | Lazy monadic conjunction. That is, when the first action returns @False@, then @False@ is immediately returned, without running the second action. @@ -84,6 +93,7 @@ chain :: (Monad m) => [a -> m a] -> (a -> m a) chain = foldr (flip (<=<)) return +-- there is also mfilter, but this should be part of Control.Monad.Plus filter :: Monad m => (a -> m Bool) -> [a] -> m [a] filter = M.filterM diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/utility-ht-0.0.11/src/Data/Bits/HT.hs new/utility-ht-0.0.12/src/Data/Bits/HT.hs --- old/utility-ht-0.0.11/src/Data/Bits/HT.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/utility-ht-0.0.12/src/Data/Bits/HT.hs 2016-09-01 19:19:05.000000000 +0200 @@ -0,0 +1,20 @@ +module Data.Bits.HT where + +import Data.Bits (Bits, shiftL, shiftR) + + +infixl 7 .<<., .>>. + +{- | +Infix variant of 'shiftL'. +Precedence is chosen like multiplication since @a .<<. k == a * 2^k@. +-} +(.<<.) :: Bits a => a -> Int -> a +(.<<.) = shiftL + +{- | +Infix variant of 'shiftR'. +Precedence is chosen like division since @a .>>. k == a / 2^k@. +-} +(.>>.) :: Bits a => a -> Int -> a +(.>>.) = shiftR diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/utility-ht-0.0.11/src/Data/List/HT/Private.hs new/utility-ht-0.0.12/src/Data/List/HT/Private.hs --- old/utility-ht-0.0.11/src/Data/List/HT/Private.hs 2015-08-19 15:11:14.000000000 +0200 +++ new/utility-ht-0.0.12/src/Data/List/HT/Private.hs 2016-09-01 19:19:05.000000000 +0200 @@ -5,10 +5,12 @@ import Data.Maybe as Maybe (fromMaybe, catMaybes, ) import Data.Maybe.HT (toMaybe, ) import Control.Monad (guard, msum, ) +import Control.Applicative ((<*>), ) import Data.Tuple.HT (mapPair, mapFst, mapSnd, forcePair, swap, ) import qualified Data.List.Key.Private as Key import qualified Data.List.Match.Private as Match +import qualified Data.List.Reverse.StrictElement as Rev import Prelude hiding (unzip, break, span, ) @@ -180,7 +182,7 @@ in recourse -chopAtRun :: (Eq a) => (a -> Bool) -> [a] -> [[a]] +chopAtRun :: (a -> Bool) -> [a] -> [[a]] chopAtRun p = let recourse [] = [[]] recourse y = @@ -193,7 +195,10 @@ Like 'break', but splits after the matching element. -} breakAfter :: (a -> Bool) -> [a] -> ([a], [a]) -breakAfter p = +breakAfter = breakAfterRec + +breakAfterRec :: (a -> Bool) -> [a] -> ([a], [a]) +breakAfterRec p = let recourse [] = ([],[]) recourse (x:xs) = mapFst (x:) $ @@ -202,6 +207,38 @@ else recourse xs in forcePair . recourse +{- +The use of 'foldr' might allow for fusion, +but unfortunately this simple implementation would copy the tail of the list. +-} +breakAfterFoldr :: (a -> Bool) -> [a] -> ([a], [a]) +breakAfterFoldr p = + forcePair . + foldr + (\x yzs -> mapFst (x:) $ if p x then ([], uncurry (++) yzs) else yzs) + ([],[]) + +breakAfterBreak :: (a -> Bool) -> [a] -> ([a], [a]) +breakAfterBreak p xs = + case break p xs of + (ys, []) -> (ys, []) + (ys, z:zs) -> (ys++[z], zs) + +breakAfterTakeUntil :: (a -> Bool) -> [a] -> ([a], [a]) +breakAfterTakeUntil p xs = + forcePair $ + (\ys -> (map fst ys, maybe [] (snd . snd) $ viewR ys)) $ + takeUntil (p . fst) $ zip xs $ tail $ tails xs + +{- | +Take all elements until one matches. +The matching element is returned, too. +This is the key difference to @takeWhile (not . p)@. +It holds @takeUntil p xs == fst (breakAfter p xs)@. +-} +takeUntil :: (a -> Bool) -> [a] -> [a] +takeUntil p = foldr (\x ys -> x : if p x then [] else ys) [] + {- | Split the list after each occurence of a terminator. @@ -452,43 +489,39 @@ dropRev :: Int -> [a] -> [a] dropRev n xs = Match.take (drop n xs) xs - {- | -Remove the longest suffix of elements satisfying p. -In contrast to @reverse . dropWhile p . reverse@ -this works for infinite lists, too. +@splitAtRev n xs == (dropRev n xs, takeRev n xs)@. +It holds @xs == uncurry (++) (splitAtRev n xs)@ -} +splitAtRev :: Int -> [a] -> ([a], [a]) +splitAtRev n xs = Match.splitAt (drop n xs) xs + + dropWhileRev :: (a -> Bool) -> [a] -> [a] dropWhileRev p = - foldr (\x xs -> if p x && null xs then [] else x:xs) [] - -dropWhileRev' :: (a -> Bool) -> [a] -> [a] -dropWhileRev' p = concat . init . segmentAfter (not . p) -{- | -Alternative version of @reverse . takeWhile p . reverse@. --} -takeWhileRev :: (a -> Bool) -> [a] -> [a] -takeWhileRev p = +takeWhileRev0 :: (a -> Bool) -> [a] -> [a] +takeWhileRev0 p = last . segmentAfter (not . p) {- | Doesn't seem to be superior to the naive implementation. -} -takeWhileRev' :: (a -> Bool) -> [a] -> [a] -takeWhileRev' p = - (\xs -> if fst (head xs) - then map snd xs - else []) . - last . Key.aux groupBy (==) p +takeWhileRev1 :: (a -> Bool) -> [a] -> [a] +takeWhileRev1 p = + (\mx -> + case mx of + Just (_, xs@((True,_):_)) -> map snd xs + _ -> []) . + viewR . Key.aux groupBy (==) p {- | However it is more inefficient, because of repeatedly appending single elements. :-( -} -takeWhileRev'' :: (a -> Bool) -> [a] -> [a] -takeWhileRev'' p = +takeWhileRev2 :: (a -> Bool) -> [a] -> [a] +takeWhileRev2 p = foldl (\xs x -> if p x then xs++[x] else []) [] @@ -498,12 +531,18 @@ @maybePrefixOf xs ys@ is @Just zs@ if @xs@ is a prefix of @ys@, where @zs@ is @ys@ without the prefix @xs@. Otherwise it is @Nothing@. +It is the same as 'Data.List.stripPrefix'. -} maybePrefixOf :: Eq a => [a] -> [a] -> Maybe [a] maybePrefixOf (x:xs) (y:ys) = guard (x==y) >> maybePrefixOf xs ys maybePrefixOf [] ys = Just ys maybePrefixOf _ [] = Nothing +maybeSuffixOf :: Eq a => [a] -> [a] -> Maybe [a] +maybeSuffixOf xs ys = + fmap reverse $ maybePrefixOf (reverse xs) (reverse ys) + + {- | Partition a list into elements which evaluate to @Just@ or @Nothing@ by @f@. @@ -699,7 +738,7 @@ transposeFill = unfoldr (\xs -> toMaybe (not (null xs)) - (mapSnd (dropWhileRev null) $ unzipCons xs)) + (mapSnd (Rev.dropWhile null) $ unzipCons xs)) unzipCons :: [[a]] -> ([Maybe a], [[a]]) unzipCons = @@ -732,7 +771,7 @@ zipConc (a:as) (b:bs) = (a++b) : zipConc as bs zipConc [] bs = bs zipConc as [] = as - in y : zipConc ys (shear' (dropWhileRev null zs)) + in y : zipConc ys (shear' (Rev.dropWhile null zs)) {- Dropping trailing empty lists is necessary, otherwise finite lists are filled with empty lists. -} shear' [] = [] @@ -947,6 +986,13 @@ mapAdjacent f xs = zipWith f xs (tail xs) {- | +<http://mail.haskell.org/libraries/2016-April/026912.html> +-} +mapAdjacentPointfree :: (a -> a -> b) -> [a] -> [b] +mapAdjacentPointfree f = zipWith f <*> tail + + +{- | > mapAdjacent f a0 [(a1,b1), (a2,b2), (a3,b3)] > == > [f a0 a1 b1, f a1 a2 b2, f a2 a3 b3] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/utility-ht-0.0.11/src/Data/List/HT.hs new/utility-ht-0.0.12/src/Data/List/HT.hs --- old/utility-ht-0.0.11/src/Data/List/HT.hs 2015-08-19 15:11:14.000000000 +0200 +++ new/utility-ht-0.0.12/src/Data/List/HT.hs 2016-09-01 19:19:05.000000000 +0200 @@ -11,6 +11,7 @@ -- * Split L.chop, L.breakAfter, + L.takeUntil, L.segmentAfter, L.segmentBefore, L.segmentAfterMaybe, @@ -26,10 +27,12 @@ -- * List processing starting at the end L.dropRev, L.takeRev, - L.dropWhileRev, - L.takeWhileRev, + L.splitAtRev, + dropWhileRev, + takeWhileRev, -- * List processing with Maybe and Either L.maybePrefixOf, + L.maybeSuffixOf, L.partitionMaybe, L.takeWhileJust, L.unzipEithers, @@ -63,3 +66,12 @@ ) where import qualified Data.List.HT.Private as L +import qualified Data.List.Reverse.StrictElement as Rev + +{-# DEPRECATED dropWhileRev "Use dropWhile from Data.List.Reverse.StrictElement or Data.List.Reverse.StrictSpine instead" #-} +dropWhileRev :: (a -> Bool) -> [a] -> [a] +dropWhileRev = Rev.dropWhile + +{-# DEPRECATED takeWhileRev "Use takeWhile from Data.List.Reverse.StrictElement or Data.List.Reverse.StrictSpine instead" #-} +takeWhileRev :: (a -> Bool) -> [a] -> [a] +takeWhileRev = Rev.takeWhile diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/utility-ht-0.0.11/src/Data/List/Reverse/StrictElement.hs new/utility-ht-0.0.12/src/Data/List/Reverse/StrictElement.hs --- old/utility-ht-0.0.11/src/Data/List/Reverse/StrictElement.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/utility-ht-0.0.12/src/Data/List/Reverse/StrictElement.hs 2016-09-01 19:19:05.000000000 +0200 @@ -0,0 +1,44 @@ +{- | +The functions in this module process the list formally from the end. +Actually they traverse the list from the start and check every element. +This way they are strict in the elements and lazy in the list spline. +Thus you can apply them to infinite lists. +Use these functions if the list is long or the test is cheap. +-} +module Data.List.Reverse.StrictElement where + +import Data.Tuple.HT (mapFst, mapSnd, forcePair, ) + +import Prelude hiding (dropWhile, takeWhile, span, ) + + +{- | +Remove the longest suffix of elements satisfying p. +In contrast to @reverse . dropWhile p . reverse@ +this works for infinite lists, too. +-} +dropWhile :: (a -> Bool) -> [a] -> [a] +dropWhile p = + foldr (\x xs -> if p x && null xs then [] else x:xs) [] + +{- | +Alternative version of @reverse . takeWhile p . reverse@. +-} +takeWhile :: (a -> Bool) -> [a] -> [a] +takeWhile p = + snd . + foldr + (\x xys -> + (if p x && fst xys then mapSnd (x:) else mapFst (const False)) xys) + (True, []) + +{- | +@span p xs == (dropWhile p xs, takeWhile p xs)@ +-} +span :: (a -> Bool) -> [a] -> ([a], [a]) +span p = + forcePair . + foldr + (\x xys -> + (if p x && null (fst xys) then mapSnd else mapFst) (x:) xys) + ([], []) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/utility-ht-0.0.11/src/Data/List/Reverse/StrictSpine.hs new/utility-ht-0.0.12/src/Data/List/Reverse/StrictSpine.hs --- old/utility-ht-0.0.11/src/Data/List/Reverse/StrictSpine.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/utility-ht-0.0.12/src/Data/List/Reverse/StrictSpine.hs 2016-09-01 19:19:05.000000000 +0200 @@ -0,0 +1,41 @@ +{- | +The functions in this module process the list from the end. +They do not access elements at the beginning if not necessary. +You can apply the function only to infinite lists. +Use these functions if the list is short and the test is expensive. +-} +module Data.List.Reverse.StrictSpine where + +import Data.Tuple.HT (mapFst, mapSnd, forcePair, ) + +import Prelude hiding (dropWhile, takeWhile, span, ) + + +{- | +Like @reverse . List.dropWhile p . reverse@. +-} +dropWhile :: (a -> Bool) -> [a] -> [a] +dropWhile p = + foldr (\x xs -> if null xs && p x then [] else x:xs) [] + +{- | +Like @reverse . List.takeWhile p . reverse@. +-} +takeWhile :: (a -> Bool) -> [a] -> [a] +takeWhile p = + snd . + foldr + (\x xys -> + (if fst xys && p x then mapSnd (x:) else mapFst (const False)) xys) + (True, []) + +{- | +@span p xs == (dropWhile p xs, takeWhile p xs)@ +-} +span :: (a -> Bool) -> [a] -> ([a], [a]) +span p = + forcePair . + foldr + (\x xys -> + (if null (fst xys) && p x then mapSnd else mapFst) (x:) xys) + ([], []) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/utility-ht-0.0.11/src/Data/String/HT.hs new/utility-ht-0.0.12/src/Data/String/HT.hs --- old/utility-ht-0.0.11/src/Data/String/HT.hs 2015-08-19 15:11:14.000000000 +0200 +++ new/utility-ht-0.0.12/src/Data/String/HT.hs 2016-09-01 19:19:05.000000000 +0200 @@ -1,8 +1,14 @@ module Data.String.HT where +import qualified Data.List.Reverse.StrictSpine as Rev import Data.Char (isSpace, ) -import Data.List.HT (dropWhileRev, ) --- | remove leading and trailing spaces +{- | +Remove leading and trailing spaces. + +We use spine strict 'Rev.dropWhile' instead of the element strict version. +This is more efficient for finite 'String's because 'isSpace' is expensive. +The downside is that 'trim' does not work for infinite 'String's. +-} trim :: String -> String -trim = dropWhileRev isSpace . dropWhile isSpace +trim = Rev.dropWhile isSpace . dropWhile isSpace diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/utility-ht-0.0.11/src/Data/Tuple/HT.hs new/utility-ht-0.0.12/src/Data/Tuple/HT.hs --- old/utility-ht-0.0.11/src/Data/Tuple/HT.hs 2015-08-19 15:11:14.000000000 +0200 +++ new/utility-ht-0.0.12/src/Data/Tuple/HT.hs 2016-09-01 19:19:05.000000000 +0200 @@ -4,6 +4,7 @@ mapFst, mapSnd, swap, + sortPair, forcePair, -- * Triple @@ -36,3 +37,7 @@ {-# INLINE curry3 #-} curry3 :: ((a, b, c) -> d) -> a -> b -> c -> d curry3 f a b c = f (a,b,c) + +sortPair, _sortPairMinMax :: (Ord a) => (a,a) -> (a,a) +sortPair (x,y) = if x<=y then (x,y) else (y,x) +_sortPairMinMax (x,y) = (min x y, max x y) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/utility-ht-0.0.11/src/Data/Tuple/Lazy.hs new/utility-ht-0.0.12/src/Data/Tuple/Lazy.hs --- old/utility-ht-0.0.11/src/Data/Tuple/Lazy.hs 2015-08-19 15:11:14.000000000 +0200 +++ new/utility-ht-0.0.12/src/Data/Tuple/Lazy.hs 2016-09-01 19:19:05.000000000 +0200 @@ -15,12 +15,12 @@ where one variant is definitely better than the other one. -} {- -Instead of lazy pattern matching with \code{(x,y)} +Instead of lazy pattern matching with \code{(a,b)} we may use \function{fst} and \function{snd}. -} {-# INLINE mapPair #-} mapPair :: (a -> c, b -> d) -> (a,b) -> (c,d) -mapPair ~(f,g) ~(x,y) = (f x, g y) +mapPair ~(f,g) ~(a,b) = (f a, g b) -- | 'Control.Arrow.first' {-# INLINE mapFst #-} @@ -32,21 +32,25 @@ mapSnd :: (b -> c) -> (a,b) -> (a,c) mapSnd f ~(a,b) = (a, f b) +{-# INLINE zipWithPair #-} +zipWithPair :: (a -> c -> e, b -> d -> f) -> (a,b) -> (c,d) -> (e,f) +zipWithPair ~(e,f) ~(a,b) ~(c,d) = (e a c, f b d) + {-# INLINE swap #-} swap :: (a,b) -> (b,a) -swap ~(x,y) = (y,x) +swap ~(a,b) = (b,a) {-# INLINE forcePair #-} forcePair :: (a,b) -> (a,b) -forcePair ~(x,y) = (x,y) +forcePair ~(a,b) = (a,b) -- * Triple {-# INLINE mapTriple #-} mapTriple :: (a -> d, b -> e, c -> f) -> (a,b,c) -> (d,e,f) -mapTriple ~(f,g,h) ~(x,y,z) = (f x, g y, h z) +mapTriple ~(f,g,h) ~(a,b,c) = (f a, g b, h c) {-# INLINE mapFst3 #-} mapFst3 :: (a -> d) -> (a,b,c) -> (d,b,c) @@ -60,6 +64,11 @@ mapThd3 :: (c -> d) -> (a,b,c) -> (a,b,d) mapThd3 f ~(a,b,c) = (a, b, f c) +{-# INLINE zipWithTriple #-} +zipWithTriple :: + (a -> d -> g, b -> e -> h, c -> f -> i) -> (a,b,c) -> (d,e,f) -> (g,h,i) +zipWithTriple ~(g,h,i) ~(a,b,c) ~(d,e,f) = (g a d, h b e, i c f) + {-# INLINE uncurry3 #-} uncurry3 :: (a -> b -> c -> d) -> ((a, b, c) -> d) uncurry3 f ~(a,b,c) = f a b c diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/utility-ht-0.0.11/src/Data/Tuple/Strict.hs new/utility-ht-0.0.12/src/Data/Tuple/Strict.hs --- old/utility-ht-0.0.11/src/Data/Tuple/Strict.hs 2015-08-19 15:11:14.000000000 +0200 +++ new/utility-ht-0.0.12/src/Data/Tuple/Strict.hs 2016-09-01 19:19:05.000000000 +0200 @@ -4,7 +4,7 @@ {-# INLINE mapPair #-} mapPair :: (a -> c, b -> d) -> (a,b) -> (c,d) -mapPair (f,g) (x,y) = (f x, g y) +mapPair (f,g) (a,b) = (f a, g b) {-# INLINE mapFst #-} mapFst :: (a -> c) -> (a,b) -> (c,b) @@ -14,17 +14,21 @@ mapSnd :: (b -> c) -> (a,b) -> (a,c) mapSnd f (a,b) = (a, f b) +{-# INLINE zipWithPair #-} +zipWithPair :: (a -> c -> e, b -> d -> f) -> (a,b) -> (c,d) -> (e,f) +zipWithPair (e,f) (a,b) (c,d) = (e a c, f b d) + {-# INLINE swap #-} swap :: (a,b) -> (b,a) -swap (x,y) = (y,x) +swap (a,b) = (b,a) -- * Triple {-# INLINE mapTriple #-} mapTriple :: (a -> d, b -> e, c -> f) -> (a,b,c) -> (d,e,f) -mapTriple (f,g,h) (x,y,z) = (f x, g y, h z) +mapTriple (f,g,h) (a,b,c) = (f a, g b, h c) {-# INLINE mapFst3 #-} mapFst3 :: (a -> d) -> (a,b,c) -> (d,b,c) @@ -38,6 +42,11 @@ mapThd3 :: (c -> d) -> (a,b,c) -> (a,b,d) mapThd3 f (a,b,c) = (a, b, f c) +{-# INLINE zipWithTriple #-} +zipWithTriple :: + (a -> d -> g, b -> e -> h, c -> f -> i) -> (a,b,c) -> (d,e,f) -> (g,h,i) +zipWithTriple (g,h,i) (a,b,c) (d,e,f) = (g a d, h b e, i c f) + {-# INLINE uncurry3 #-} uncurry3 :: (a -> b -> c -> d) -> ((a, b, c) -> d) uncurry3 f (a,b,c) = f a b c diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/utility-ht-0.0.11/src/Test/Data/List/Reverse/StrictElement.hs new/utility-ht-0.0.12/src/Test/Data/List/Reverse/StrictElement.hs --- old/utility-ht-0.0.11/src/Test/Data/List/Reverse/StrictElement.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/utility-ht-0.0.12/src/Test/Data/List/Reverse/StrictElement.hs 2016-09-01 19:19:05.000000000 +0200 @@ -0,0 +1,53 @@ +module Test.Data.List.Reverse.StrictElement where + +import qualified Data.List.Reverse.StrictElement as Rev +import qualified Data.List as List +import Data.Tuple.HT (mapPair, swap, ) + +import Test.QuickCheck (Testable, quickCheck, ) + +import Prelude hiding (takeWhile, dropWhile, span, ) + + +takeWhile :: (Ord a) => (a -> Bool) -> [a] -> Bool +takeWhile p xs = + Rev.takeWhile p xs == reverse (List.takeWhile p (reverse xs)) + +dropWhile :: (Ord a) => (a -> Bool) -> [a] -> Bool +dropWhile p xs = + Rev.dropWhile p xs == reverse (List.dropWhile p (reverse xs)) + +span :: (Ord a) => (a -> Bool) -> [a] -> Bool +span p xs = + Rev.span p xs == swap (mapPair (reverse, reverse) (List.span p (reverse xs))) + +spanTakeDrop :: (Ord a) => (a -> Bool) -> [a] -> Bool +spanTakeDrop p xs = + Rev.span p xs == (Rev.dropWhile p xs, Rev.takeWhile p xs) + +dropWhileInf :: (Ord a) => a -> [a] -> Bool +dropWhileInf x xs = + let ys = List.take 1000 $ Rev.dropWhile (x/=) $ cycle $ x:xs + in ys==ys + +spanInf :: (Ord a) => a -> [a] -> Bool +spanInf x xs = + let ys = List.take 1000 $ fst $ Rev.span (x/=) $ cycle $ x:xs + in ys==ys + + +simple :: + (Testable test) => + (Float -> [Float] -> test) -> IO () +simple = quickCheck + + +tests :: [(String, IO ())] +tests = + ("takeWhile", simple (\a -> takeWhile (a>=))) : + ("dropWhile", simple (\a -> dropWhile (a>=))) : + ("span", simple (\a -> span (a>=))) : + ("spanTakeDrop", simple (\a -> spanTakeDrop (a>=))) : + ("dropWhileInf", simple dropWhileInf) : + ("spanInf", simple spanInf) : + [] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/utility-ht-0.0.11/src/Test/Data/List/Reverse/StrictSpine.hs new/utility-ht-0.0.12/src/Test/Data/List/Reverse/StrictSpine.hs --- old/utility-ht-0.0.11/src/Test/Data/List/Reverse/StrictSpine.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/utility-ht-0.0.12/src/Test/Data/List/Reverse/StrictSpine.hs 2016-09-01 19:19:05.000000000 +0200 @@ -0,0 +1,62 @@ +module Test.Data.List.Reverse.StrictSpine where + +import qualified Data.List.Reverse.StrictSpine as Rev +import qualified Data.List.Match as Match +import qualified Data.List as List +import Data.Tuple.HT (mapFst, mapPair, swap, ) + +import Test.QuickCheck (Testable, quickCheck, ) + +import Prelude hiding (takeWhile, dropWhile, span, ) + + +takeWhile :: (Ord a) => (a -> Bool) -> [a] -> Bool +takeWhile p xs = + Rev.takeWhile p xs == reverse (List.takeWhile p (reverse xs)) + +dropWhile :: (Ord a) => (a -> Bool) -> [a] -> Bool +dropWhile p xs = + Rev.dropWhile p xs == reverse (List.dropWhile p (reverse xs)) + +span :: (Ord a) => (a -> Bool) -> [a] -> Bool +span p xs = + Rev.span p xs == swap (mapPair (reverse, reverse) (List.span p (reverse xs))) + +spanTakeDrop :: (Ord a) => (a -> Bool) -> [a] -> Bool +spanTakeDrop p xs = + Rev.span p xs == (Rev.dropWhile p xs, Rev.takeWhile p xs) + +takeWhileBottom :: (Ord a) => a -> [a] -> [a] -> Bool +takeWhileBottom x xs pad = + let ys = Rev.takeWhile (x/=) $ Match.replicate pad undefined ++ x:xs + in ys==ys + +dropWhileBottom :: (Ord a) => a -> [a] -> [a] -> Bool +dropWhileBottom x xs pad = + let n = length $ Rev.dropWhile (x/=) $ Match.replicate pad undefined ++ x:xs + in n==n + +spanBottom :: (Ord a) => a -> [a] -> [a] -> Bool +spanBottom x xs pad = + let (n,ys) = + mapFst length $ Rev.span (x/=) $ + Match.replicate pad undefined ++ x:xs + in n==n && ys==ys + + +simple :: + (Testable test) => + (Float -> [Float] -> test) -> IO () +simple = quickCheck + + +tests :: [(String, IO ())] +tests = + ("takeWhile", simple (\a -> takeWhile (a>=))) : + ("dropWhile", simple (\a -> dropWhile (a>=))) : + ("span", simple (\a -> span (a>=))) : + ("spanTakeDrop", simple (\a -> spanTakeDrop (a>=))) : + ("takeWhileBottom", simple takeWhileBottom) : + ("dropWhileBottom", simple dropWhileBottom) : + ("spanBottom", simple spanBottom) : + [] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/utility-ht-0.0.11/src/Test/Data/List.hs new/utility-ht-0.0.12/src/Test/Data/List.hs --- old/utility-ht-0.0.11/src/Test/Data/List.hs 2015-08-19 15:11:14.000000000 +0200 +++ new/utility-ht-0.0.12/src/Test/Data/List.hs 2016-09-01 19:19:05.000000000 +0200 @@ -1,5 +1,6 @@ module Test.Data.List where +import qualified Data.List.Reverse.StrictElement as Rev import qualified Data.List.HT.Private as ListHT import qualified Data.List as List import Control.Monad (liftM2, ) @@ -11,13 +12,21 @@ -takeWhileRev :: (Ord a) => (a -> Bool) -> [a] -> Bool -takeWhileRev p xs = - ListHT.takeWhileRev p xs == reverse (takeWhile p (reverse xs)) +takeWhileRev0 :: (Eq a) => (a -> Bool) -> [a] -> Bool +takeWhileRev0 p xs = + ListHT.takeWhileRev0 p xs == Rev.takeWhile p xs + +takeWhileRev1 :: (Eq a) => (a -> Bool) -> [a] -> Bool +takeWhileRev1 p xs = + ListHT.takeWhileRev1 p xs == Rev.takeWhile p xs + +takeWhileRev2 :: (Eq a) => (a -> Bool) -> [a] -> Bool +takeWhileRev2 p xs = + ListHT.takeWhileRev2 p xs == Rev.takeWhile p xs -dropWhileRev :: (Ord a) => (a -> Bool) -> [a] -> Bool +dropWhileRev :: (Eq a) => (a -> Bool) -> [a] -> Bool dropWhileRev p xs = - ListHT.dropWhileRev p xs == reverse (dropWhile p (reverse xs)) + ListHT.dropWhileRev p xs == Rev.dropWhile p xs takeRev :: (Eq a) => Int -> [a] -> Bool @@ -28,6 +37,31 @@ dropRev n xs = ListHT.dropRev n xs == reverse (drop n (reverse xs)) +splitAtRev :: (Eq a) => Int -> [a] -> Bool +splitAtRev n xs = + xs == uncurry (++) (ListHT.splitAtRev n xs) + + +breakAfterAppend :: (Eq a) => (a -> Bool) -> [a] -> Bool +breakAfterAppend p xs = + uncurry (++) (ListHT.breakAfter p xs) == xs + +breakAfter0 :: (Eq a) => (a -> Bool) -> [a] -> Bool +breakAfter0 p xs = + ListHT.breakAfterRec p xs == ListHT.breakAfterFoldr p xs + +breakAfter1 :: (Eq a) => (a -> Bool) -> [a] -> Bool +breakAfter1 p xs = + ListHT.breakAfterRec p xs == ListHT.breakAfterBreak p xs + +breakAfter2 :: (Eq a) => (a -> Bool) -> [a] -> Bool +breakAfter2 p xs = + ListHT.breakAfterRec p xs == ListHT.breakAfterTakeUntil p xs + +breakAfterUntil :: (Eq a) => (a -> Bool) -> [a] -> Bool +breakAfterUntil p xs = + ListHT.takeUntil p xs == fst (ListHT.breakAfter p xs) + sieve :: Eq a => Int -> [a] -> Property sieve n x = @@ -84,19 +118,36 @@ mapAdjacent x xs = ListHT.mapAdjacent subtract (scanl (+) x xs) == xs +mapAdjacentPointfree :: (Num a, Eq a) => [a] -> Bool +mapAdjacentPointfree xs = + ListHT.mapAdjacent (+) xs == ListHT.mapAdjacentPointfree (+) xs + simple :: (Testable test) => (Int -> [Integer] -> test) -> IO () simple = quickCheck +elemCheck :: + (Testable test) => + (Float -> [Float] -> test) -> IO () +elemCheck = quickCheck + tests :: [(String, IO ())] tests = - ("takeWhileRev", quickCheck (\a -> takeWhileRev ((a::Integer)>=))) : - ("dropWhileRev", quickCheck (\a -> dropWhileRev ((a::Integer)>=))) : + ("takeWhileRev0", elemCheck (\a -> takeWhileRev0 (a>=))) : + ("takeWhileRev1", elemCheck (\a -> takeWhileRev1 (a>=))) : + ("takeWhileRev2", elemCheck (\a -> takeWhileRev2 (a>=))) : + ("dropWhileRev", elemCheck (\a -> dropWhileRev (a>=))) : ("takeRev", simple takeRev) : ("dropRev", simple dropRev) : + ("splitAtRev", simple splitAtRev) : + ("breakAfterAppend", elemCheck (\a -> breakAfterAppend (a>=))) : + ("breakAfter0", elemCheck (\a -> breakAfter0 (a>=))) : + ("breakAfter1", elemCheck (\a -> breakAfter1 (a>=))) : + ("breakAfter2", elemCheck (\a -> breakAfter2 (a>=))) : + ("breakAfterUntil", elemCheck (\a -> breakAfterUntil (a>=))) : ("sieve", simple sieve) : ("sliceHorizontal", simple sliceHorizontal) : ("sliceVertical", simple sliceVertical) : @@ -105,4 +156,6 @@ ("outerProduct", quickCheck (outerProduct :: [Integer] -> [Int] -> Bool)) : ("iterate", quickCheck (iterate (+) :: Integer -> Bool)) : ("mapAdjacent", quickCheck (mapAdjacent :: Integer -> [Integer] -> Bool)) : + ("mapAdjacentPointfree", + quickCheck (mapAdjacentPointfree :: [Integer] -> Bool)) : [] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/utility-ht-0.0.11/src/Test.hs new/utility-ht-0.0.12/src/Test.hs --- old/utility-ht-0.0.11/src/Test.hs 2015-08-19 15:11:14.000000000 +0200 +++ new/utility-ht-0.0.12/src/Test.hs 2016-09-01 19:19:05.000000000 +0200 @@ -1,5 +1,7 @@ module Main where +import qualified Test.Data.List.Reverse.StrictElement as RevElem +import qualified Test.Data.List.Reverse.StrictSpine as RevSpine import qualified Test.Data.List as ListHT import qualified Test.Data.ListMatch as ListMatch import qualified Test.Data.Maybe as MaybeHT @@ -14,6 +16,8 @@ main = mapM_ (\(msg,io) -> putStr (msg++": ") >> io) $ concat $ + prefix "ReverseSpine" RevSpine.tests : + prefix "ReverseElem" RevElem.tests : prefix "List" ListHT.tests : prefix "ListMatch" ListMatch.tests : prefix "Maybe" MaybeHT.tests : diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/utility-ht-0.0.11/utility-ht.cabal new/utility-ht-0.0.12/utility-ht.cabal --- old/utility-ht-0.0.11/utility-ht.cabal 2015-08-19 15:11:14.000000000 +0200 +++ new/utility-ht-0.0.12/utility-ht.cabal 2016-09-01 19:19:05.000000000 +0200 @@ -1,5 +1,5 @@ Name: utility-ht -Version: 0.0.11 +Version: 0.0.12 License: BSD3 License-File: LICENSE Author: Henning Thielemann <hask...@henning-thielemann.de> @@ -27,6 +27,7 @@ Tested-With: GHC==7.0.2, GHC==7.2.2, GHC==7.4.1, GHC==7.8.2 Cabal-Version: >=1.10 Build-Type: Simple +Stability: Stable -- workaround for Cabal-1.10 Extra-Source-Files: @@ -44,7 +45,7 @@ Source-Repository this type: darcs location: http://code.haskell.org/~thielema/utility/ - tag: 0.0.11 + tag: 0.0.12 Library Build-Depends: @@ -54,6 +55,7 @@ GHC-Options: -Wall Hs-Source-Dirs: src Exposed-Modules: + Data.Bits.HT Data.Bool.HT Data.Eq.HT Data.Function.HT @@ -61,6 +63,8 @@ Data.List.HT Data.List.Key Data.List.Match + Data.List.Reverse.StrictElement + Data.List.Reverse.StrictSpine Data.Maybe.HT Data.Monoid.HT Data.Ord.HT @@ -70,6 +74,7 @@ Data.Tuple.Lazy Data.Tuple.Strict Control.Monad.HT + Control.Applicative.HT Control.Functor.HT Data.Strictness.HT Text.Read.HT @@ -96,6 +101,8 @@ Other-Modules: Test.Data.List Test.Data.ListMatch + Test.Data.List.Reverse.StrictElement + Test.Data.List.Reverse.StrictSpine Test.Data.Maybe Test.Data.Function Test.Utility