{-# OPTIONS_HADDOCK show-extensions #-}
{-# LANGUAGE NoImplicitPrelude #-}

-- |
-- Module      :  Phladiprelio.UniquenessPeriodsG
-- Copyright   :  (c) OleksandrZhabenko 2020-2023
-- License     :  MIT
-- Stability   :  Experimental
-- Maintainer  :  oleksandr.zhabenko@yahoo.com
--
-- Generalization of the uniqueness-periods and uniqueness-periods-general
-- packages functionality for small 'F.Foldable' data structures. Uses less dependencies.
--

{-# LANGUAGE BangPatterns #-}

module Phladiprelio.UniquenessPeriodsG (
  -- * List functions
  uniquenessPeriodsGG
  , uniquenessPeriodsG
  , uniquenessPeriodsGI8
  , diverse2GGL
  , diverse2GL
  , diverse2GLInt8
)  where

import GHC.Base
import GHC.Int
import Data.List hiding (foldr)
import GHC.Num ((-))
import Data.Tuple
import Data.Maybe (mapMaybe)
import qualified Data.Foldable as F

-- | A generalization of the uniquenessPeriods function of the @uniqueness-periods@ package.
uniquenessPeriodsGG :: (F.Foldable t1, F.Foldable t2, F.Foldable t3, Ord a) => t3 a -> t1 a -> t2 a -> [Int16]
uniquenessPeriodsGG :: forall (t1 :: * -> *) (t2 :: * -> *) (t3 :: * -> *) a.
(Foldable t1, Foldable t2, Foldable t3, Ord a) =>
t3 a -> t1 a -> t2 a -> [Int16]
uniquenessPeriodsGG t3 a
sels t1 a
whspss t2 a
ws
 | forall (t :: * -> *) a. Foldable t => t a -> Bool
F.null t2 a
ws = []
 | Bool
otherwise = forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (forall a (t1 :: * -> *) (t2 :: * -> *) (t3 :: * -> *) b.
(Eq a, Foldable t1, Foldable t2, Foldable t3) =>
t3 a -> (t1 b -> b) -> t2 a -> (t1 b, a) -> Maybe b
helpGSel t3 a
sels forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
F.sum t1 a
whspss) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b a. (b -> Maybe (a, b)) -> b -> [a]
unfoldr forall {a}.
Eq a =>
[(Int16, a)] -> Maybe (([Int16], a), [(Int16, a)])
f forall a b. (a -> b) -> a -> b
$ [(Int16, a)]
ks
     where !ks :: [(Int16, a)]
ks = forall (t :: * -> *) b. Foldable t => t b -> [(Int16, b)]
indexedL t2 a
ws
           !vs :: [Int16]
vs = forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe forall {a}. (a, a) -> Maybe a
g [(Int16, a)]
ks
           g :: (a, a) -> Maybe a
g (a
x,a
y)
            | a
y forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`F.elem` t1 a
whspss = forall a. a -> Maybe a
Just a
x
            | Bool
otherwise = forall a. Maybe a
Nothing
           {-# INLINE g #-}
           f :: [(Int16, a)] -> Maybe (([Int16], a), [(Int16, a)])
f ys :: [(Int16, a)]
ys@((Int16, a)
y:[(Int16, a)]
_) = let !idX0 :: a
idX0 = forall a b. (a, b) -> b
snd (Int16, a)
y in forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\([(Int16, a)]
v2,[(Int16, a)]
v3) -> (([Int16] -> [Int16] -> [Int16] -> [Int16]
helpUPV3 [Int16]
vs [] forall b c a. (b -> c) -> (a -> b) -> a -> c
.
                    forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> a
fst forall a b. (a -> b) -> a -> b
$ [(Int16, a)]
v2,forall a b. (a, b) -> b
snd forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> a
head forall a b. (a -> b) -> a -> b
$ [(Int16, a)]
v2),[(Int16, a)]
v3)) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> ([a], [a])
partition (\(Int16
_,a
xs) -> a
xs forall a. Eq a => a -> a -> Bool
== a
idX0) forall a b. (a -> b) -> a -> b
$ [(Int16, a)]
ys
           f [(Int16, a)]
_ = forall a. Maybe a
Nothing
{-# INLINE uniquenessPeriodsGG #-}

-- | A general variant of the diversity property. Use it in general case.
diverse2GGL :: (F.Foldable t1, F.Foldable t2, F.Foldable t3, Ord a) => t3 a -> t1 a -> t2 a -> Int16
diverse2GGL :: forall (t1 :: * -> *) (t2 :: * -> *) (t3 :: * -> *) a.
(Foldable t1, Foldable t2, Foldable t3, Ord a) =>
t3 a -> t1 a -> t2 a -> Int16
diverse2GGL t3 a
sels t1 a
whspss = forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t1 :: * -> *) (t2 :: * -> *) (t3 :: * -> *) a.
(Foldable t1, Foldable t2, Foldable t3, Ord a) =>
t3 a -> t1 a -> t2 a -> [Int16]
uniquenessPeriodsGG t3 a
sels t1 a
whspss
{-# INLINE diverse2GGL #-}

-- | A variant of the 'diverse2GGL' function for 'Char'.
diverse2GL :: (F.Foldable t1, F.Foldable t2) => t1 Char -> t2 Char -> Int16
diverse2GL :: forall (t1 :: * -> *) (t2 :: * -> *).
(Foldable t1, Foldable t2) =>
t1 Char -> t2 Char -> Int16
diverse2GL = forall (t1 :: * -> *) (t2 :: * -> *) (t3 :: * -> *) a.
(Foldable t1, Foldable t2, Foldable t3, Ord a) =>
t3 a -> t1 a -> t2 a -> Int16
diverse2GGL []
{-# INLINE diverse2GL #-}
--
-- | A variant for the 'uniquenessPeriodsGG' function for 'Char'.
uniquenessPeriodsG :: (F.Foldable t1, F.Foldable t2) => t1 Char -> t2 Char -> [Int16]
uniquenessPeriodsG :: forall (t1 :: * -> *) (t2 :: * -> *).
(Foldable t1, Foldable t2) =>
t1 Char -> t2 Char -> [Int16]
uniquenessPeriodsG = forall (t1 :: * -> *) (t2 :: * -> *) (t3 :: * -> *) a.
(Foldable t1, Foldable t2, Foldable t3, Ord a) =>
t3 a -> t1 a -> t2 a -> [Int16]
uniquenessPeriodsGG []
{-# INLINE uniquenessPeriodsG #-}

-- | A variant of the 'diverse2GGL' function for 'Int8'.
diverse2GLInt8 :: (F.Foldable t1, F.Foldable t2) => t1 Int8 -> t2 Int8 -> Int16
diverse2GLInt8 :: forall (t1 :: * -> *) (t2 :: * -> *).
(Foldable t1, Foldable t2) =>
t1 Int8 -> t2 Int8 -> Int16
diverse2GLInt8 = forall (t1 :: * -> *) (t2 :: * -> *) (t3 :: * -> *) a.
(Foldable t1, Foldable t2, Foldable t3, Ord a) =>
t3 a -> t1 a -> t2 a -> Int16
diverse2GGL []
{-# INLINE diverse2GLInt8 #-}

-- | A variant for the 'uniquenessPeriodsGG' function for 'Int8'.
uniquenessPeriodsGI8 :: (F.Foldable t1, F.Foldable t2) => t1 Int8 -> t2 Int8 -> [Int16]
uniquenessPeriodsGI8 :: forall (t1 :: * -> *) (t2 :: * -> *).
(Foldable t1, Foldable t2) =>
t1 Int8 -> t2 Int8 -> [Int16]
uniquenessPeriodsGI8 = forall (t1 :: * -> *) (t2 :: * -> *) (t3 :: * -> *) a.
(Foldable t1, Foldable t2, Foldable t3, Ord a) =>
t3 a -> t1 a -> t2 a -> [Int16]
uniquenessPeriodsGG []
{-# INLINE uniquenessPeriodsGI8 #-}

-- | The first and the third list arguments of numbers (if not empty) must be sorted in the ascending order.
helpUPV3 :: [Int16] -> [Int16] -> [Int16] -> [Int16]
helpUPV3 :: [Int16] -> [Int16] -> [Int16] -> [Int16]
helpUPV3 ks :: [Int16]
ks@(!Int16
z:[Int16]
zs) ![Int16]
acc ps :: [Int16]
ps@(!Int16
x:qs :: [Int16]
qs@(!Int16
y:[Int16]
_))
 | Int16
z forall a. Ord a => a -> a -> Bool
< Int16
y Bool -> Bool -> Bool
&& Int16
z forall a. Ord a => a -> a -> Bool
> Int16
x = [Int16] -> [Int16] -> [Int16] -> [Int16]
helpUPV3 [Int16]
zs ((Int16
y forall a. Num a => a -> a -> a
- Int16
x)forall a. a -> [a] -> [a]
:[Int16]
acc) [Int16]
qs 
 | Int16
z forall a. Ord a => a -> a -> Bool
< Int16
y = [Int16] -> [Int16] -> [Int16] -> [Int16]
helpUPV3 [Int16]
zs [Int16]
acc [Int16]
ps
 | Bool
otherwise = [Int16] -> [Int16] -> [Int16] -> [Int16]
helpUPV3 [Int16]
ks [Int16]
acc [Int16]
qs
helpUPV3 [Int16]
_ ![Int16]
acc [Int16]
_ = [Int16]
acc

indexedL :: F.Foldable t => t b -> [(Int16, b)]
indexedL :: forall (t :: * -> *) b. Foldable t => t b -> [(Int16, b)]
indexedL = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
F.foldr forall {a} {b}. Num a => b -> [(a, b)] -> [(a, b)]
f []
  where f :: b -> [(a, b)] -> [(a, b)]
f b
x ((a
j,b
z):[(a, b)]
ys) = (a
jforall a. Num a => a -> a -> a
-a
1,b
x)forall a. a -> [a] -> [a]
:(a
j,b
z)forall a. a -> [a] -> [a]
:[(a, b)]
ys
        f b
x [(a, b)]
_ = [(a
1,b
x)]

helpG :: (Eq a, F.Foldable t1, F.Foldable t2) => (t1 b -> b) -> t2 a -> (t1 b, a) -> Maybe b
helpG :: forall a (t1 :: * -> *) (t2 :: * -> *) b.
(Eq a, Foldable t1, Foldable t2) =>
(t1 b -> b) -> t2 a -> (t1 b, a) -> Maybe b
helpG t1 b -> b
h t2 a
xs (t1 b
ts, a
x)
  | forall (t :: * -> *) a. Foldable t => t a -> Bool
F.null t1 b
ts = forall a. Maybe a
Nothing
  | a
x forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`F.elem` t2 a
xs = forall a. Maybe a
Nothing
  | Bool
otherwise = forall a. a -> Maybe a
Just (t1 b -> b
h t1 b
ts)
{-# INLINE helpG #-}

helpGSel :: (Eq a, F.Foldable t1, F.Foldable t2, F.Foldable t3) => t3 a -> (t1 b -> b) -> t2 a -> (t1 b, a) -> Maybe b
helpGSel :: forall a (t1 :: * -> *) (t2 :: * -> *) (t3 :: * -> *) b.
(Eq a, Foldable t1, Foldable t2, Foldable t3) =>
t3 a -> (t1 b -> b) -> t2 a -> (t1 b, a) -> Maybe b
helpGSel t3 a
sels t1 b -> b
h t2 a
xs (t1 b
ts, a
x)
  | forall (t :: * -> *) a. Foldable t => t a -> Bool
F.null t3 a
sels = forall a (t1 :: * -> *) (t2 :: * -> *) b.
(Eq a, Foldable t1, Foldable t2) =>
(t1 b -> b) -> t2 a -> (t1 b, a) -> Maybe b
helpG t1 b -> b
h t2 a
xs (t1 b
ts,a
x)
  | forall (t :: * -> *) a. Foldable t => t a -> Bool
F.null t1 b
ts = forall a. Maybe a
Nothing
  | a
x forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`F.elem` t2 a
xs = forall a. Maybe a
Nothing
  | a
x forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`F.elem` t3 a
sels = forall a. a -> Maybe a
Just (t1 b -> b
h t1 b
ts)
  | Bool
otherwise = forall a. Maybe a
Nothing
{-# INLINE helpGSel #-}