diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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.
diff --git a/Data/MinMax.hs b/Data/MinMax.hs
--- a/Data/MinMax.hs
+++ b/Data/MinMax.hs
@@ -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))
diff --git a/Data/MinMax/Preconditions.hs b/Data/MinMax/Preconditions.hs
new file mode 100644
--- /dev/null
+++ b/Data/MinMax/Preconditions.hs
@@ -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))
diff --git a/Data/MinMax3Plus.hs b/Data/MinMax3Plus.hs
--- a/Data/MinMax3Plus.hs
+++ b/Data/MinMax3Plus.hs
@@ -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))
diff --git a/Data/MinMax3Plus/Preconditions.hs b/Data/MinMax3Plus/Preconditions.hs
new file mode 100644
--- /dev/null
+++ b/Data/MinMax3Plus/Preconditions.hs
@@ -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))
diff --git a/subG.cabal b/subG.cabal
--- a/subG.cabal
+++ b/subG.cabal
@@ -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
