subG 0.2.0.0 → 0.2.1.0
raw patch · 4 files changed
+79/−58 lines, 4 files
Files
- CHANGELOG.md +6/−0
- Data/MinMax.hs +22/−18
- Data/SubG.hs +50/−39
- subG.cabal +1/−1
CHANGELOG.md view
@@ -16,3 +16,9 @@ * Second version. Added new functions to the Data.SubG module. Added a new module Data.MinMax with the functions that allow to find out both minimum and maximum elements of the Foldable structures.++## 0.2.1.0 -- 2020-11-18++* Second version revised A. Fixed issues with the ambiguous names in the further reverse dependencies on the package. Now the ambiguous functions have+in their names suffix G (it means 'generalization'). Added a new function splitAtEndG to the Data.SubG module. Fixed issues with multiple search minimum and+maximum elements functions in the module Data.MinMax. Allowed equal elements in the structures so they are now general. Some documentation improvements.
Data/MinMax.hs view
@@ -9,10 +9,11 @@ module Data.MinMax where -import Prelude hiding (drop,take,splitAt)+import Prelude hiding (takeWhile,dropWhile,span) import Data.Maybe (fromJust) import Data.SubG import qualified Data.Foldable as F+import qualified Data.List as L (sort) -- | Returns a pair where the first element is the minimum element from the two given ones and the second one is the maximum. If the arguments are -- equal then the tuple contains equal elements.@@ -35,7 +36,7 @@ minMax xs | F.null xs = Nothing | otherwise = Just . F.foldr f (x,x) $ xs- where x = fromJust . safeHead $ xs+ where x = fromJust . safeHeadG $ xs f z (x,y) | z < x = (z,y) | z > y = (x,z)@@ -46,7 +47,7 @@ minMaxBy g xs | F.null xs = Nothing | otherwise = Just . F.foldr f (x,x) $ xs- where x = fromJust . safeHead $ xs+ where x = fromJust . safeHeadG $ xs f z (x,y) | g z x == LT = (z,y) | g z y == GT = (x,z)@@ -54,13 +55,14 @@ -- | Given a finite structure with at least 3 elements returns a tuple with the two most minimum elements -- (the first one is less than the second one) and the maximum element. If the structure has less elements, returns 'Nothing'.--- All the elements must be pairwise unequal though this is not checked. Uses just two passes through the structure, so may be more efficient than--- some other approaches.-minMax21 :: (Ord a, Foldable t) => t a -> Maybe ((a,a), a)+-- Uses just three passes through the structure, so may be more efficient than some other approaches.+minMax21 :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> Maybe ((a,a), a) minMax21 xs | F.length xs < 3 = Nothing- | otherwise = Just . F.foldr f ((x,x),x) $ xs- where x = fromJust . safeHead $ xs+ | otherwise = Just . F.foldr f ((n,p),q) $ str1+ where x = fromJust . safeHeadG $ xs+ (str1,str2) = splitAtEndG 3 xs+ [n,p,q] = L.sort . F.toList $ str2 f z ((x,y),t) | z > t = ((x,y),z) | z < y = if z > x then ((x,z),t) else ((z,x),t)@@ -68,13 +70,14 @@ -- | Given a finite structure with at least 3 elements returns a tuple with the minimum element -- and two maximum elements (the first one is less than the second one). If the structure has less elements, returns 'Nothing'.--- All the elements must be pairwise unequal though this is not checked. Uses just two passes through the structure, so may be more efficient than--- some other approaches.-minMax12 :: (Ord a, Foldable t) => t a -> Maybe (a, (a,a))+-- Uses just three passes through the structure, so may be more efficient than some other approaches.+minMax12 :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> Maybe (a, (a,a)) minMax12 xs | F.length xs < 3 = Nothing- | otherwise = Just . F.foldr f (x,(x,x)) $ xs- where x = fromJust . safeHead $ xs+ | otherwise = Just . F.foldr f (n,(p,q)) $ str1+ where x = fromJust . safeHeadG $ xs+ (str1,str2) = splitAtEndG 3 xs+ [n,p,q] = L.sort . F.toList $ str2 f z (x,(y,t)) | z < x = (z,(y,t)) | z > y = if z < t then (x,(z,t)) else (x,(t,z))@@ -82,13 +85,14 @@ -- | Given a finite structure with at least 4 elements returns a tuple with two minimum elements -- and two maximum elements. If the structure has less elements, returns 'Nothing'.--- All the elements must be pairwise unequal though this is not checked. Uses just two passes through the structure, so may be more efficient than--- some other approaches.-minMax22 :: (Ord a, Foldable t) => t a -> Maybe ((a,a), (a,a))+-- Uses just three passes through the structure, so may be more efficient than some other approaches.+minMax22 :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> Maybe ((a,a), (a,a)) minMax22 xs | F.length xs < 4 = Nothing- | otherwise = Just . F.foldr f ((x,x),(x,x)) $ xs- where x = fromJust . safeHead $ xs+ | otherwise = Just . F.foldr f ((n,p),(q,r)) $ str1+ where x = fromJust . safeHeadG $ xs+ (str1,str2) = splitAtEndG 4 xs+ [n,p,q,r] = L.sort . F.toList $ str2 f z ((x,y),(t,w)) | z < y = if z > x then ((x,z),(t,w)) else ((z,x),(t,w)) | z > t = if z < w then ((x,y),(z,w)) else ((x,y),(w,z))
Data/SubG.hs view
@@ -13,25 +13,27 @@ module Data.SubG ( InsertLeft(..) , subG- , take- , takeFromEnd- , reverseTake- , reverseTakeFromEnd- , drop- , dropFromEnd- , reverseDrop- , reverseDropFromEnd+ , takeG+ , takeFromEndG+ , reverseTakeG+ , reverseTakeFromEndG+ , dropG+ , dropFromEndG+ , reverseDropG+ , reverseDropFromEndG , takeWhile , dropWhile , span+ , splitAtG+ , splitAtEndG , preAppend- , safeHead- , safeTail- , safeInit- , safeLast+ , safeHeadG+ , safeTailG+ , safeInitG+ , safeLastG ) where -import Prelude hiding (dropWhile, span, takeWhile,drop,take,splitAt)+import Prelude hiding (dropWhile, span, takeWhile) import qualified Data.Foldable as F import Data.Monoid @@ -101,8 +103,8 @@ -- | Inspired by: Graham Hutton. A tutorial on the universality and expressiveness of fold. /J. Functional Programming/ 9 (4): 355–372, July 1999. -- that is available at the URL: https://www.cs.nott.ac.uk/~pszgmh/fold.pdf. -- Takes the first argument quantity from the right end of the structure preserving the order.-takeFromEnd :: (Integral b, InsertLeft t a, Monoid (t a)) => b -> t a -> t a-takeFromEnd n = (\(xs,_,_) -> xs) . F.foldr f v+takeFromEndG :: (Integral b, InsertLeft t a, Monoid (t a)) => b -> t a -> t a+takeFromEndG n = (\(xs,_,_) -> xs) . F.foldr f v where v = (mempty,0,n) f x (zs,k,n) | k < n = (x %@ zs,k + 1,n)@@ -111,8 +113,8 @@ -- | Inspired by: Graham Hutton. A tutorial on the universality and expressiveness of fold. /J. Functional Programming/ 9 (4): 355–372, July 1999. -- that is available at the URL: https://www.cs.nott.ac.uk/~pszgmh/fold.pdf. -- Takes the specified quantity from the right end of the structure and then reverses the result.-reverseTakeFromEnd :: (Integral b, InsertLeft t a, Monoid (t a)) => b -> t a -> t a-reverseTakeFromEnd n = (\(xs,_,_) -> xs) . F.foldr f v+reverseTakeFromEndG :: (Integral b, InsertLeft t a, Monoid (t a)) => b -> t a -> t a+reverseTakeFromEndG n = (\(xs,_,_) -> xs) . F.foldr f v where v = (mempty,0,n) f x (zs,k,n) | k < n = (zs `mappend` (x %@ mempty),k + 1,n)@@ -122,8 +124,8 @@ -- that is available at the URL: https://www.cs.nott.ac.uk/~pszgmh/fold.pdf. -- Is analogous to the taking the specified quantity from the structure and then reversing the result. Uses strict variant of the foldl, so is -- not suitable for large amounts of data.-reverseTake :: (Integral b, InsertLeft t a, Monoid (t a)) => b -> t a -> t a-reverseTake n = (\(xs,_,_) -> xs) . F.foldl' f v+reverseTakeG :: (Integral b, InsertLeft t a, Monoid (t a)) => b -> t a -> t a+reverseTakeG n = (\(xs,_,_) -> xs) . F.foldl' f v where v = (mempty,0,n) f (zs,k,n) x | k < n = (x %@ zs,k + 1,n)@@ -132,8 +134,8 @@ -- | Inspired by: Graham Hutton. A tutorial on the universality and expressiveness of fold. /J. Functional Programming/ 9 (4): 355–372, July 1999. -- that is available at the URL: https://www.cs.nott.ac.uk/~pszgmh/fold.pdf. Uses strict variant of the foldl, so is -- strict and the data must be finite.-take :: (Integral b, InsertLeft t a, Monoid (t a)) => b -> t a -> t a-take n = (\(xs,_,_) -> xs) . F.foldl' f v+takeG :: (Integral b, InsertLeft t a, Monoid (t a)) => b -> t a -> t a+takeG n = (\(xs,_,_) -> xs) . F.foldl' f v where v = (mempty,0,n) f (zs,k,n) x | k < n = (zs `mappend` (x %@ mempty),k + 1,n)@@ -143,8 +145,8 @@ -- that is available at the URL: https://www.cs.nott.ac.uk/~pszgmh/fold.pdf. -- Is analogous to the dropping the specified quantity from the structure and then reversing the result. Uses strict variant of the foldl, so is -- strict and the data must be finite.-reverseDrop :: (Integral b, InsertLeft t a, Monoid (t a)) => b -> t a -> t a-reverseDrop n = (\(xs,_,_) -> xs) . F.foldl' f v+reverseDropG :: (Integral b, InsertLeft t a, Monoid (t a)) => b -> t a -> t a+reverseDropG n = (\(xs,_,_) -> xs) . F.foldl' f v where v = (mempty,0,n) f (zs,k,n) x | k < n = (mempty,k + 1,n)@@ -153,8 +155,8 @@ -- | Inspired by: Graham Hutton. A tutorial on the universality and expressiveness of fold. /J. Functional Programming/ 9 (4): 355–372, July 1999. -- that is available at the URL: https://www.cs.nott.ac.uk/~pszgmh/fold.pdf. -- Drops the first argument quantity from the right end of the structure and returns the result preserving the order.-dropFromEnd :: (Integral b, InsertLeft t a, Monoid (t a)) => b -> t a -> t a-dropFromEnd n = (\(xs,_,_) -> xs) . F.foldr f v+dropFromEndG :: (Integral b, InsertLeft t a, Monoid (t a)) => b -> t a -> t a+dropFromEndG n = (\(xs,_,_) -> xs) . F.foldr f v where v = (mempty,0,n) f x (zs,k,n) | k < n = (mempty,k + 1,n)@@ -163,8 +165,8 @@ -- | Inspired by: Graham Hutton. A tutorial on the universality and expressiveness of fold. /J. Functional Programming/ 9 (4): 355–372, July 1999. -- that is available at the URL: https://www.cs.nott.ac.uk/~pszgmh/fold.pdf. -- Drops the specified quantity from the right end of the structure and then reverses the result.-reverseDropFromEnd :: (Integral b, InsertLeft t a, Monoid (t a)) => b -> t a -> t a-reverseDropFromEnd n = (\(xs,_,_) -> xs) . F.foldr f v+reverseDropFromEndG :: (Integral b, InsertLeft t a, Monoid (t a)) => b -> t a -> t a+reverseDropFromEndG n = (\(xs,_,_) -> xs) . F.foldr f v where v = (mempty,0,n) f x (zs,k,n) | k < n = (mempty,k + 1,n)@@ -173,8 +175,8 @@ -- | Inspired by: Graham Hutton. A tutorial on the universality and expressiveness of fold. /J. Functional Programming/ 9 (4): 355–372, July 1999. -- that is available at the URL: https://www.cs.nott.ac.uk/~pszgmh/fold.pdf. Uses strict variant of the foldl, so is -- strict and the data must be finite.-drop :: (Integral b, InsertLeft t a, Monoid (t a)) => b -> t a -> t a-drop n = (\(xs,_,_) -> xs) . F.foldl' f v+dropG :: (Integral b, InsertLeft t a, Monoid (t a)) => b -> t a -> t a+dropG n = (\(xs,_,_) -> xs) . F.foldl' f v where v = (mempty,0,n) f (zs,k,n) x | k < n = (mempty,k + 1,n)@@ -183,26 +185,35 @@ -- | Inspired by: Graham Hutton. A tutorial on the universality and expressiveness of fold. /J. Functional Programming/ 9 (4): 355–372, July 1999. -- that is available at the URL: https://www.cs.nott.ac.uk/~pszgmh/fold.pdf. Uses strict variant of the foldl, so is -- strict and the data must be finite.-splitAt :: (Integral b, InsertLeft t a, Monoid (t a)) => b -> t a -> (t a, t a)-splitAt n = (\(x,y,_,_) -> (x,y)) . F.foldl' f v+splitAtG :: (Integral b, InsertLeft t a, Monoid (t a)) => b -> t a -> (t a, t a)+splitAtG n = (\(x,y,_,_) -> (x,y)) . F.foldl' f v where v = (mempty,mempty,0,n) f (zs,ts,k,n) x | k < n = (zs `mappend` (x %@ mempty),mempty,k + 1,n) | otherwise = (zs,ts `mappend` (x %@ mempty),k + 1,n) +-- | Inspired by: Graham Hutton. A tutorial on the universality and expressiveness of fold. /J. Functional Programming/ 9 (4): 355–372, July 1999.+-- that is available at the URL: https://www.cs.nott.ac.uk/~pszgmh/fold.pdf. Splits the structure starting from the end and preserves the order.+splitAtEndG :: (Integral b, InsertLeft t a, Monoid (t a)) => b -> t a -> (t a, t a)+splitAtEndG n = (\(x,y,_,_) -> (y,x)) . F.foldr f v+ where v = (mempty,mempty,0,n)+ f x (zs,ts,k,n)+ | k < n = (x %@ zs,mempty,k + 1,n)+ | otherwise = (zs,x %@ ts,k + 1,n)+ -- | If a structure is empty, just returns 'Nothing'.-safeHead :: (Foldable t) => t a -> Maybe a-safeHead = F.find (const True)+safeHeadG :: (Foldable t) => t a -> Maybe a+safeHeadG = F.find (const True) -- | If the structure is empty, just returns itself. Uses strict variant of the foldl, so is -- strict and the data must be finite.-safeTail :: (InsertLeft t a, Monoid (t a)) => t a -> t a-safeTail = drop 1+safeTailG :: (InsertLeft t a, Monoid (t a)) => t a -> t a+safeTailG = dropG 1 -- | If the structure is empty, just returns itself.-safeInit :: (InsertLeft t a, Monoid (t a)) => t a -> t a-safeInit = dropFromEnd 1+safeInitG :: (InsertLeft t a, Monoid (t a)) => t a -> t a+safeInitG = dropFromEndG 1 -- | If the structure is empty, just returns 'Nothing'.-safeLast :: (InsertLeft t a, Monoid (t a)) => t a -> Maybe a-safeLast = F.find (const True) . takeFromEnd 1+safeLastG :: (InsertLeft t a, Monoid (t a)) => t a -> Maybe a+safeLastG = F.find (const True) . takeFromEndG 1
subG.cabal view
@@ -2,7 +2,7 @@ -- see http://haskell.org/cabal/users-guide/ name: subG-version: 0.2.0.0+version: 0.2.1.0 synopsis: Some extension to the Foldable and Monoid classes. description: Introduces a new class InsertLeft -- the class of types of values that can be inserted from the left to the Foldable structure that is a data that is also the Monoid instance. Also contains some functions to find out both minimum and maximum elements of the finite Foldable structures. homepage: https://hackage.haskell.org/package/subG