packages feed

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 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