subG 0.3.0.0 → 0.4.0.0
raw patch · 6 files changed
+266/−87 lines, 6 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Data.MinMax: minMax :: (Ord a, Foldable t) => t a -> Maybe (a, a)
- Data.MinMax: minMaxBy :: (Ord a, Foldable t) => (a -> a -> Ordering) -> t a -> Maybe (a, a)
+ Data.MinMax: betweenNXBy :: Ord a => (a -> a -> Ordering) -> a -> a -> a -> Bool
+ Data.MinMax: minMax11 :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> Maybe (a, a)
+ Data.MinMax: minMax11By :: (Ord a, InsertLeft t a, Monoid (t a)) => (a -> a -> Ordering) -> t a -> Maybe (a, a)
+ Data.MinMax: minMax12By :: (Ord a, InsertLeft t a, Monoid (t a)) => (a -> a -> Ordering) -> t a -> Maybe (a, (a, a))
+ Data.MinMax: minMax21By :: (Ord a, InsertLeft t a, Monoid (t a)) => (a -> a -> Ordering) -> t a -> Maybe ((a, a), a)
+ Data.MinMax: minMax22By :: (Ord a, InsertLeft t a, Monoid (t a)) => (a -> a -> Ordering) -> t a -> Maybe ((a, a), (a, a))
+ Data.MinMax: minmaxPBy :: Ord a => (a -> a -> Ordering) -> a -> a -> (a, a)
+ Data.MinMax.Preconditions: minMax11ByC :: (Ord a, InsertLeft t a, Monoid (t a)) => (a -> a -> Ordering) -> t a -> (a, a)
+ Data.MinMax.Preconditions: minMax11C :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> (a, a)
+ Data.MinMax.Preconditions: minMax12ByC :: (Ord a, InsertLeft t a, Monoid (t a)) => (a -> a -> Ordering) -> t a -> (a, (a, a))
+ Data.MinMax.Preconditions: minMax12C :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> (a, (a, a))
+ Data.MinMax.Preconditions: minMax21ByC :: (Ord a, InsertLeft t a, Monoid (t a)) => (a -> a -> Ordering) -> t a -> ((a, a), a)
+ Data.MinMax.Preconditions: minMax21C :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> ((a, a), a)
+ Data.MinMax.Preconditions: minMax22ByC :: (Ord a, InsertLeft t a, Monoid (t a)) => (a -> a -> Ordering) -> t a -> ((a, a), (a, a))
+ Data.MinMax.Preconditions: minMax22C :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> ((a, a), (a, a))
+ Data.MinMax3Plus: minMax23By :: (Ord a, InsertLeft t a, Monoid (t a)) => (a -> a -> Ordering) -> t a -> ((a, a), (a, a, a))
+ Data.MinMax3Plus: minMax32By :: (Ord a, InsertLeft t a, Monoid (t a)) => (a -> a -> Ordering) -> t a -> ((a, a, a), (a, a))
+ Data.MinMax3Plus: minMax33By :: (Ord a, InsertLeft t a, Monoid (t a)) => (a -> a -> Ordering) -> t a -> ((a, a, a), (a, a, a))
+ Data.MinMax3Plus.Preconditions: minMax23ByC :: (Ord a, InsertLeft t a, Monoid (t a)) => (a -> a -> Ordering) -> t a -> ((a, a), (a, a, a))
+ Data.MinMax3Plus.Preconditions: minMax23C :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> ((a, a), (a, a, a))
+ Data.MinMax3Plus.Preconditions: minMax32ByC :: (Ord a, InsertLeft t a, Monoid (t a)) => (a -> a -> Ordering) -> t a -> ((a, a, a), (a, a))
+ Data.MinMax3Plus.Preconditions: minMax32C :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> ((a, a, a), (a, a))
+ Data.MinMax3Plus.Preconditions: minMax33ByC :: (Ord a, InsertLeft t a, Monoid (t a)) => (a -> a -> Ordering) -> t a -> ((a, a, a), (a, a, a))
+ Data.MinMax3Plus.Preconditions: minMax33C :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> ((a, a, a), (a, a, a))
- Data.MinMax3Plus: minMax23 :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> Maybe ((a, a), (a, a, a))
+ Data.MinMax3Plus: minMax23 :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> ((a, a), (a, a, a))
- Data.MinMax3Plus: minMax32 :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> Maybe ((a, a, a), (a, a))
+ Data.MinMax3Plus: minMax32 :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> ((a, a, a), (a, a))
- Data.MinMax3Plus: minMax33 :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> Maybe ((a, a, a), (a, a, a))
+ Data.MinMax3Plus: minMax33 :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> ((a, a, a), (a, a, a))
Files
- CHANGELOG.md +5/−0
- Data/MinMax.hs +57/−42
- Data/MinMax/Preconditions.hs +85/−0
- Data/MinMax3Plus.hs +49/−43
- Data/MinMax3Plus/Preconditions.hs +68/−0
- subG.cabal +2/−2
CHANGELOG.md view
@@ -26,3 +26,8 @@ ## 0.3.0.0 -- 2020-11-18 * Third version. Added a new module Data.MinMax3Plus with additional functions.++## 0.4.0.0 -- 2020-11-18++* Fourth version. Added new modules Data.MinMax3Plus.Preconditions and Data.MinMax.Preconditions with additional functions. Added -By functions to the modules+to make them more general. The modules with Preconditions in the names just use functions with no checking the needed length of the structure.
Data/MinMax.hs view
@@ -10,44 +10,47 @@ module Data.MinMax where 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)+import qualified Data.List as L (sortBy) -- | 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. minmaxP :: (Ord a) => a -> a -> (a,a)-minmaxP x y- | x < y = (x,y)+minmaxP = minmaxPBy compare+{-# INLINE minmaxP #-}++-- | A variant of the 'minmaxP' where you can specify your own comparison function.+minmaxPBy :: (Ord a) => (a -> a -> Ordering) -> a -> a -> (a,a)+minmaxPBy g x y+ | g x y == LT = (x,y) | otherwise = (y,x) -- | A ternary predicate to check whether the third argument lies between the first two unequal ones or whether they are all equal. betweenNX :: (Ord a) => a -> a -> a -> Bool-betweenNX x y z+betweenNX = betweenNXBy compare+{-# INLINE betweenNX #-}++-- | A variant of the 'betweenNX' where you can specify your own comparison function.+betweenNXBy :: (Ord a) => (a -> a -> Ordering) -> a -> a -> a -> Bool+betweenNXBy g x y z | x == y = x == z- | z < k && z > t = True+ | g z k == LT && g z t == GT = True | otherwise = False- where (t,k) = minmaxP x y+ where (t,k) = minmaxPBy g x y --- | Finds out the minimum and maximum values of the finite structure. If the latter one is empty returns 'Nothing', if all the elements are equal--- (or it has just one) then it returns 'Just' tuple of equal elements.-minMax :: (Ord a, Foldable t) => t a -> Maybe (a, a)-minMax xs- | F.null xs = Nothing- | otherwise = Just . F.foldr f (x,x) $ xs- where x = fromJust . safeHeadG $ xs- f z (x,y)- | z < x = (z,y)- | z > y = (x,z)- | otherwise = (x,y)+-- | Finds out the minimum and maximum values of the finite structure that has not less than two elements. Otherwise returns 'Nothing'.+minMax11 :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> Maybe (a, a)+minMax11 = minMax11By compare+{-# INLINE minMax11 #-} --- | A generalized variant of the 'minMax' where you can specify your own comparison function.-minMaxBy :: (Ord a, Foldable t) => (a -> a -> Ordering) -> t a -> Maybe (a, a)-minMaxBy g xs- | F.null xs = Nothing- | otherwise = Just . F.foldr f (x,x) $ xs- where x = fromJust . safeHeadG $ xs+-- | A generalized variant of the 'minMax11' where you can specify your own comparison function.+minMax11By :: (Ord a, InsertLeft t a, Monoid (t a)) => (a -> a -> Ordering) -> t a -> Maybe (a, a)+minMax11By g xs+ | F.length xs < 2 = Nothing+ | otherwise = Just . F.foldr f (t,u) $ str1+ where (str1,str2) = splitAtEndG 2 $ xs+ [t,u] = L.sortBy g . F.toList $ str2 f z (x,y) | g z x == LT = (z,y) | g z y == GT = (x,z)@@ -57,43 +60,55 @@ -- (the first one is less than the second one) and the maximum element. If the structure has less elements, returns 'Nothing'. -- 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+minMax21 = minMax21By compare+{-# INLINE minMax21 #-}++-- | A variant of the 'minMax21' where you can specify your own comparison function.+minMax21By :: (Ord a, InsertLeft t a, Monoid (t a)) => (a -> a -> Ordering) -> t a -> Maybe ((a,a), a)+minMax21By g xs | F.length xs < 3 = Nothing | 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+ where (str1,str2) = splitAtEndG 3 xs+ [n,p,q] = L.sortBy g . 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)+ | g z t == GT = ((x,y),z)+ | g z y == LT = if g z x == GT then ((x,z),t) else ((z,x),t) | otherwise = ((x,y),t) -- | 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'. -- 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+minMax12 = minMax12By compare+{-# INLINE minMax12 #-}++-- | A variant of the 'minMax12' where you can specify your own comparison function.+minMax12By :: (Ord a, InsertLeft t a, Monoid (t a)) => (a -> a -> Ordering) -> t a -> Maybe (a, (a,a))+minMax12By g xs | F.length xs < 3 = Nothing | 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+ where (str1,str2) = splitAtEndG 3 xs+ [n,p,q] = L.sortBy g . 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))+ | g z x == LT = (z,(y,t))+ | g z y == GT = if g z t == LT then (x,(z,t)) else (x,(t,z)) | otherwise = (x,(y,t)) -- | 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'. -- 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+minMax22 = minMax22By compare+{-# INLINE minMax22 #-}++-- | A variant of the 'minMax22' where you can specify your own comparison function.+minMax22By :: (Ord a, InsertLeft t a, Monoid (t a)) => (a -> a -> Ordering) -> t a -> Maybe ((a,a), (a,a))+minMax22By g xs | F.length xs < 4 = Nothing | 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+ where (str1,str2) = splitAtEndG 4 xs+ [n,p,q,r] = L.sortBy g . 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))+ | g z y == LT = if g z x == GT then ((x,z),(t,w)) else ((z,x),(t,w))+ | g z t == GT = if g z w == LT then ((x,y),(z,w)) else ((x,y),(w,z)) | otherwise = ((x,y),(t,w))
+ Data/MinMax/Preconditions.hs view
@@ -0,0 +1,85 @@+-- |+-- Module : Data.MinMax.Preconditions+-- Copyright : (c) OleksandrZhabenko 2020+-- License : MIT+-- Stability : Experimental+-- Maintainer : olexandr543@yahoo.com+--+-- Functions to find both minimum and maximum elements of the 'F.Foldable' structure of the 'Ord'ered elements. With the preconditions that the+-- structure at least have enough elements (this is contrary to the functions from the module Data.MinMax not checked internally).++module Data.MinMax.Preconditions where++import Prelude hiding (takeWhile,dropWhile,span)+import Data.SubG+import qualified Data.Foldable as F+import qualified Data.List as L (sortBy)++-- | Finds out the minimum and maximum values of the finite structure that has not less than two elements.+minMax11C :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> (a, a)+minMax11C = minMax11ByC compare+{-# INLINE minMax11C #-}++-- | A generalized variant of the 'minMax' where you can specify your own comparison function.+minMax11ByC :: (Ord a, InsertLeft t a, Monoid (t a)) => (a -> a -> Ordering) -> t a -> (a, a)+minMax11ByC g xs =+ F.foldr f (t,u) str1+ where (str1,str2) = splitAtEndG 2 $ xs+ [t,u] = L.sortBy g . F.toList $ str2+ f z (x,y)+ | g z x == LT = (z,y)+ | g z y == GT = (x,z)+ | otherwise = (x,y)++-- | Given a finite structure returns a tuple with the two most minimum elements+-- (the first one is less than the second one) and the maximum element.+-- Uses just two passes through the structure, so may be more efficient than some other approaches.+minMax21C :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> ((a,a), a)+minMax21C = minMax21ByC compare+{-# INLINE minMax21C #-}++-- | A variant of the 'minMax21C' where you can specify your own comparison function.+minMax21ByC :: (Ord a, InsertLeft t a, Monoid (t a)) => (a -> a -> Ordering) -> t a -> ((a,a), a)+minMax21ByC g xs =+ F.foldr f ((n,p),q) str1+ where (str1,str2) = splitAtEndG 3 xs+ [n,p,q] = L.sortBy g . F.toList $ str2+ f z ((x,y),t)+ | g z t == GT = ((x,y),z)+ | g z y == LT = if g z x == GT then ((x,z),t) else ((z,x),t)+ | otherwise = ((x,y),t)++-- | Given a finite structure returns a tuple with the minimum element+-- and two maximum elements (the first one is less than the second one).+-- Uses just two passes through the structure, so may be more efficient than some other approaches.+minMax12C :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> (a, (a,a))+minMax12C = minMax12ByC compare+{-# INLINE minMax12C #-}++-- | A variant of the 'minMax12C' where you can specify your own comparison function.+minMax12ByC :: (Ord a, InsertLeft t a, Monoid (t a)) => (a -> a -> Ordering) -> t a -> (a, (a,a))+minMax12ByC g xs =+ F.foldr f (n,(p,q)) $ str1+ where (str1,str2) = splitAtEndG 3 xs+ [n,p,q] = L.sortBy g . F.toList $ str2+ f z (x,(y,t))+ | g z x == LT = (z,(y,t))+ | g z y == GT = if g z t == LT then (x,(z,t)) else (x,(t,z))+ | otherwise = (x,(y,t))++-- | Given a finite structure returns a tuple with two minimum elements+-- and two maximum elements. Uses just two passes through the structure, so may be more efficient than some other approaches.+minMax22C :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> ((a,a), (a,a))+minMax22C = minMax22ByC compare+{-# INLINE minMax22C #-}++-- | A variant of the 'minMax22C' where you can specify your own comparison function.+minMax22ByC :: (Ord a, InsertLeft t a, Monoid (t a)) => (a -> a -> Ordering) -> t a -> ((a,a), (a,a))+minMax22ByC g xs =+ F.foldr f ((n,p),(q,r)) $ str1+ where (str1,str2) = splitAtEndG 4 xs+ [n,p,q,r] = L.sortBy g . F.toList $ str2+ f z ((x,y),(t,w))+ | g z y == LT = if g z x == GT then ((x,z),(t,w)) else ((z,x),(t,w))+ | g z t == GT = if g z w == LT then ((x,y),(z,w)) else ((x,y),(w,z))+ | otherwise = ((x,y),(t,w))
Data/MinMax3Plus.hs view
@@ -10,52 +10,58 @@ module Data.MinMax3Plus where 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)+import qualified Data.List as L (sortBy) --- | Given a finite structure with at least 5 elements returns a tuple with two minimum elements--- and three maximum elements. If the structure has less elements, returns 'Nothing'.+-- | Given a finite structure returns a tuple with two minimum elements+-- and three maximum elements. -- Uses just three passes through the structure, so may be more efficient than some other approaches.-minMax23 :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> Maybe ((a,a), (a,a,a))-minMax23 xs- | F.length xs < 5 = Nothing- | otherwise = Just . F.foldr f ((n,p),(q,r,s)) $ str1- where x = fromJust . safeHeadG $ xs- (str1,str2) = splitAtEndG 5 xs- [n,p,q,r,s] = L.sort . F.toList $ str2- f z ((x,y),(t,w,u))- | z < y = if z > x then ((x,z),(t,w,u)) else ((z,x),(t,w,u))- | z > t = if z < w then ((x,y),(z,w,u)) else if z < u then ((x,y),(w,z,u)) else ((x,y),(t,w,u))- | otherwise = ((x,y),(t,w,u))+minMax23 :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> ((a,a), (a,a,a))+minMax23 = minMax23By compare+{-# INLINE minMax23 #-} --- | Given a finite structure with at least 5 elements returns a tuple with three minimum elements--- and two maximum elements. If the structure has less elements, returns 'Nothing'.--- Uses just three passes through the structure, so may be more efficient than some other approaches.-minMax32 :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> Maybe ((a,a,a), (a,a))-minMax32 xs- | F.length xs < 5 = Nothing- | otherwise = Just . F.foldr f ((n,m,p),(q,r)) $ str1- where x = fromJust . safeHeadG $ xs- (str1,str2) = splitAtEndG 5 xs- [n,m,p,q,r] = L.sort . F.toList $ str2- f z ((x,y,u),(t,w))- | z < u = if z > y then ((x,y,z),(t,w)) else if z > x then ((x,z,y),(t,w)) else ((z,x,y),(t,w))- | z > t = if z < w then ((x,y,u),(z,w)) else ((x,y,u),(w,z))- | otherwise = ((x,y,u),(t,w))+-- | A variant of the 'minMax23' where you can specify your own comparison function.+minMax23By :: (Ord a, InsertLeft t a, Monoid (t a)) => (a -> a -> Ordering) -> t a -> ((a,a), (a,a,a))+minMax23By g xs =+ F.foldr f ((n,p),(q,r,s)) $ str1+ where (str1,str2) = splitAtEndG 5 xs+ [n,p,q,r,s] = L.sortBy g . F.toList $ str2+ f z ((x,y),(t,w,u))+ | g z y == LT = if g z x == GT then ((x,z),(t,w,u)) else ((z,x),(t,w,u))+ | g z t == GT = if g z w == LT then ((x,y),(z,w,u)) else if g z u == LT then ((x,y),(w,z,u)) else ((x,y),(t,w,u))+ | otherwise = ((x,y),(t,w,u)) --- | Given a finite structure with at least 6 elements returns a tuple with three minimum elements--- and three maximum elements. If the structure has less elements, returns 'Nothing'.--- Uses just three passes through the structure, so may be more efficient than some other approaches.-minMax33 :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> Maybe ((a,a,a), (a,a,a))-minMax33 xs- | F.length xs < 6 = Nothing- | otherwise = Just . F.foldr f ((n,m,p),(q,r,s)) $ str1- where x = fromJust . safeHeadG $ xs- (str1,str2) = splitAtEndG 6 xs- [n,m,p,q,r,s] = L.sort . F.toList $ str2- f z ((x,y,u),(t,w,k))- | z < u = if z > y then ((x,y,z),(t,w,k)) else if z > x then ((x,z,y),(t,w,k)) else ((z,x,y),(t,w,k))- | z > t = if z < w then ((x,y,u),(z,w,k)) else if z < k then ((x,y,u),(w,z,k)) else ((x,y,u),(w,k,z))- | otherwise = ((x,y,u),(t,w,k))+-- | Given a finite structure returns a tuple with three minimum elements+-- and two maximum elements. Uses just three passes through the structure, so may be more efficient than some other approaches.+minMax32 :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> ((a,a,a), (a,a))+minMax32 = minMax32By compare+{-# INLINE minMax32 #-}++-- | A variant of the 'minMax32' where you can specify your own comparison function.+minMax32By :: (Ord a, InsertLeft t a, Monoid (t a)) => (a -> a -> Ordering) -> t a -> ((a,a,a), (a,a))+minMax32By g xs =+ F.foldr f ((n,m,p),(q,r)) $ str1+ where (str1,str2) = splitAtEndG 5 xs+ [n,m,p,q,r] = L.sortBy g . F.toList $ str2+ f z ((x,y,u),(t,w))+ | g z u == LT = if g z y == GT then ((x,y,z),(t,w)) else if g z x == GT then ((x,z,y),(t,w)) else ((z,x,y),(t,w))+ | g z t == GT = if g z w == LT then ((x,y,u),(z,w)) else ((x,y,u),(w,z))+ | otherwise = ((x,y,u),(t,w))++-- | Given a finite structure returns a tuple with three minimum elements+-- and three maximum elements. Uses just three passes through the structure, so may be more efficient than some other approaches.+minMax33 :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> ((a,a,a), (a,a,a))+minMax33 = minMax33By compare+{-# INLINE minMax33 #-}++-- | A variant of the 'minMax33' where you can specify your own comparison function.+minMax33By :: (Ord a, InsertLeft t a, Monoid (t a)) => (a -> a -> Ordering) -> t a -> ((a,a,a), (a,a,a))+minMax33By g xs =+ F.foldr f ((n,m,p),(q,r,s)) $ str1+ where (str1,str2) = splitAtEndG 6 xs+ [n,m,p,q,r,s] = L.sortBy g . F.toList $ str2+ f z ((x,y,u),(t,w,k))+ | g z u == LT = if g z y == GT then ((x,y,z),(t,w,k)) else if g z x == GT then ((x,z,y),(t,w,k)) else ((z,x,y),(t,w,k))+ | g z t == GT = if g z w == LT then ((x,y,u),(z,w,k)) else if g z k == LT then ((x,y,u),(w,z,k)) else ((x,y,u),(w,k,z))+ | otherwise = ((x,y,u),(t,w,k))
+ Data/MinMax3Plus/Preconditions.hs view
@@ -0,0 +1,68 @@+-- |+-- Module : Data.MinMax3Plus.Preconditions+-- Copyright : (c) OleksandrZhabenko 2020+-- License : MIT+-- Stability : Experimental+-- Maintainer : olexandr543@yahoo.com+--+-- Functions to find both minimum and maximum elements of the 'F.Foldable' structure of the 'Ord'ered elements. With the preconditions that the+-- structure at least have enough elements (this is contrary to the functions from the module Data.MinMax not checked internally).++module Data.MinMax3Plus.Preconditions where++import Prelude hiding (takeWhile,dropWhile,span)+import Data.SubG+import qualified Data.Foldable as F+import qualified Data.List as L (sortBy)++-- | Given a finite structure returns a tuple with two minimum elements+-- and three maximum elements.+-- Uses just two passes through the structure, so may be more efficient than some other approaches.+minMax23C :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> ((a,a), (a,a,a))+minMax23C = minMax23ByC compare+{-# INLINE minMax23C #-}++-- | A variant of the 'minMax23C' where you can specify your own comparison function.+minMax23ByC :: (Ord a, InsertLeft t a, Monoid (t a)) => (a -> a -> Ordering) -> t a -> ((a,a), (a,a,a))+minMax23ByC g xs =+ F.foldr f ((n,p),(q,r,s)) $ str1+ where (str1,str2) = splitAtEndG 5 xs+ [n,p,q,r,s] = L.sortBy g . F.toList $ str2+ f z ((x,y),(t,w,u))+ | g z y == LT = if g z x == GT then ((x,z),(t,w,u)) else ((z,x),(t,w,u))+ | g z t == GT = if g z w == LT then ((x,y),(z,w,u)) else if g z u == LT then ((x,y),(w,z,u)) else ((x,y),(t,w,u))+ | otherwise = ((x,y),(t,w,u))++-- | Given a finite structure returns a tuple with three minimum elements+-- and two maximum elements. Uses just two passes through the structure, so may be more efficient than some other approaches.+minMax32C :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> ((a,a,a), (a,a))+minMax32C = minMax32ByC compare+{-# INLINE minMax32C #-}++-- | A variant of the 'minMax32C' where you can specify your own comparison function.+minMax32ByC :: (Ord a, InsertLeft t a, Monoid (t a)) => (a -> a -> Ordering) -> t a -> ((a,a,a), (a,a))+minMax32ByC g xs =+ F.foldr f ((n,m,p),(q,r)) $ str1+ where (str1,str2) = splitAtEndG 5 xs+ [n,m,p,q,r] = L.sortBy g . F.toList $ str2+ f z ((x,y,u),(t,w))+ | g z u == LT = if g z y == GT then ((x,y,z),(t,w)) else if g z x == GT then ((x,z,y),(t,w)) else ((z,x,y),(t,w))+ | g z t == GT = if g z w == LT then ((x,y,u),(z,w)) else ((x,y,u),(w,z))+ | otherwise = ((x,y,u),(t,w))++-- | Given a finite structure returns a tuple with three minimum elements+-- and three maximum elements. Uses just two passes through the structure, so may be more efficient than some other approaches.+minMax33C :: (Ord a, InsertLeft t a, Monoid (t a)) => t a -> ((a,a,a), (a,a,a))+minMax33C = minMax33ByC compare+{-# INLINE minMax33C #-}++-- | A variant of the 'minMax33C' where you can specify your own comparison function.+minMax33ByC :: (Ord a, InsertLeft t a, Monoid (t a)) => (a -> a -> Ordering) -> t a -> ((a,a,a), (a,a,a))+minMax33ByC g xs =+ F.foldr f ((n,m,p),(q,r,s)) $ str1+ where (str1,str2) = splitAtEndG 6 xs+ [n,m,p,q,r,s] = L.sortBy g . F.toList $ str2+ f z ((x,y,u),(t,w,k))+ | g z u == LT = if g z y == GT then ((x,y,z),(t,w,k)) else if g z x == GT then ((x,z,y),(t,w,k)) else ((z,x,y),(t,w,k))+ | g z t == GT = if g z w == LT then ((x,y,u),(z,w,k)) else if g z k == LT then ((x,y,u),(w,z,k)) else ((x,y,u),(w,k,z))+ | otherwise = ((x,y,u),(t,w,k))
subG.cabal view
@@ -2,7 +2,7 @@ -- see http://haskell.org/cabal/users-guide/ name: subG-version: 0.3.0.0+version: 0.4.0.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@@ -17,7 +17,7 @@ cabal-version: >=1.10 library- exposed-modules: Data.SubG, Data.MinMax, Data.MinMax3Plus+ exposed-modules: Data.SubG, Data.MinMax, Data.MinMax3Plus, Data.MinMax.Preconditions, Data.MinMax3Plus.Preconditions -- other-modules: other-extensions: MultiParamTypeClasses, FlexibleInstances build-depends: base >=4.8 && <4.15