-- |
-- Module      :  DobutokO.Sound.Functional.Split
-- Copyright   :  (c) OleksandrZhabenko 2020, 2024
-- License     :  MIT
-- Stability   :  Experimental
-- Maintainer  :  oleksandr.zhabenko@yahoo.com
--
-- Helps to create experimental music from a file (or its part) and a Ukrainian text. 
-- It can also generate a timbre for the notes. Uses SoX inside.

{-# OPTIONS_GHC -threaded #-}

module DobutokO.Sound.Functional.Split (
  -- * Splitting and concatenating OvertonesO
  splitO
  , splitO2
  , overConcat
  -- ** Generalization of the previous ones splitting functions
  , splitHelp1
  , splitHelp2
  , splitOG1
  , splitOG2
  , splitOG12
  , splitOG12S
  , splitOG22
  , splitOG22S
) where

import CaseBi.Arr (getBFstLSorted')
import Data.Char (isAsciiLower)
import Data.List (sortBy)
import qualified Data.Vector as V
import DobutokO.Sound.Functional.Basics


-- | Splits (with addition of the new overtones) a given 'OvertonesO' into a number @n@ (specified by the first 'Int' argument) of 'OvertonesO' 
-- (represented finally as a 'V.Vector' of them respectively) so that all except the first @n@ greatest by the absolute value of the amplitude 
-- tuples of Floats are considered overtones for the greatest by the absolute value one in the given 'OvertonesO' and all the next @n - 1@ 
-- are treated as the greatest by the absolute value and each of them produces the similar by the @f :: Float -> OvertonesO@ function overtones.
-- 
-- It is expected to obtain by such a conversion a splitted one sound into several simultaneous similar ones with different heights. 
-- To provide a rich result, the given first argument must be strictly less than the length of the given 'OvertonesO' minus one.
splitO :: Int -> OvertonesO -> V.Vector OvertonesO
splitO :: Int -> OvertonesO -> Vector OvertonesO
splitO Int
n OvertonesO
v0 
 | Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (OvertonesO -> Int
forall a. Vector a -> Int
V.length OvertonesO
v0) (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
GT = 
    let v1 :: OvertonesO
v1 = [(Float, Float)] -> OvertonesO
forall a. [a] -> Vector a
V.fromList ([(Float, Float)] -> OvertonesO)
-> (OvertonesO -> [(Float, Float)]) -> OvertonesO -> OvertonesO
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Float, Float) -> (Float, Float) -> Ordering)
-> [(Float, Float)] -> [(Float, Float)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (\(Float
x1,Float
_) (Float
x2,Float
_) -> Float -> Float -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Float -> Float
forall a. Num a => a -> a
abs Float
x2) (Float -> Float
forall a. Num a => a -> a
abs Float
x1)) ([(Float, Float)] -> [(Float, Float)])
-> (OvertonesO -> [(Float, Float)])
-> OvertonesO
-> [(Float, Float)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OvertonesO -> [(Float, Float)]
forall a. Vector a -> [a]
V.toList (OvertonesO -> OvertonesO) -> OvertonesO -> OvertonesO
forall a b. (a -> b) -> a -> b
$ OvertonesO
v0
        (Float
x0, Float
y0) = OvertonesO -> Int -> (Float, Float)
forall a. Vector a -> Int -> a
V.unsafeIndex OvertonesO
v1 Int
0
        v2 :: OvertonesO
v2 = Int -> Int -> OvertonesO -> OvertonesO
forall a. Int -> Int -> Vector a -> Vector a
V.unsafeSlice Int
1 (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) OvertonesO
v1
        v31 :: Vector Float
v31 = ((Float, Float) -> Float) -> OvertonesO -> Vector Float
forall a b. (a -> b) -> Vector a -> Vector b
V.map (\(Float, Float)
t -> ((Float, Float) -> Float
forall a b. (a, b) -> a
fst (Float, Float)
t) Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
x0) OvertonesO
v2
        v32 :: Vector Float
v32 = ((Float, Float) -> Float) -> OvertonesO -> Vector Float
forall a b. (a -> b) -> Vector a -> Vector b
V.map (\(Float, Float)
t -> ((Float, Float) -> Float
forall a b. (a, b) -> b
snd (Float, Float)
t) Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
y0) OvertonesO
v2
        v3 :: OvertonesO
v3 = Vector Float -> Vector Float -> OvertonesO
forall a b. Vector a -> Vector b -> Vector (a, b)
V.zip Vector Float
v31 Vector Float
v32
        f1Tup :: (Float, Float) -> OvertonesO
f1Tup (Float
t1, Float
w2) = (Int -> (Float, Float) -> (Float, Float))
-> OvertonesO -> OvertonesO
forall a b. (Int -> a -> b) -> Vector a -> Vector b
V.imap (\ Int
i (Float, Float)
_ -> ((Float, Float) -> Float
forall a b. (a, b) -> a
fst (OvertonesO -> Int -> (Float, Float)
forall a. Vector a -> Int -> a
V.unsafeIndex OvertonesO
v3 Int
i) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
t1, (Float, Float) -> Float
forall a b. (a, b) -> b
snd (OvertonesO -> Int -> (Float, Float)
forall a. Vector a -> Int -> a
V.unsafeIndex OvertonesO
v3 Int
i) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
w2)) OvertonesO
v3
          in ((Float, Float) -> OvertonesO) -> OvertonesO -> Vector OvertonesO
forall a b. (a -> b) -> Vector a -> Vector b
V.map (Float, Float) -> OvertonesO
f1Tup (Int -> Int -> OvertonesO -> OvertonesO
forall a. Int -> Int -> Vector a -> Vector a
V.unsafeSlice Int
0 Int
n OvertonesO
v1)
 | Bool
otherwise = OvertonesO -> Vector OvertonesO
forall a. a -> Vector a
V.singleton OvertonesO
v0

-- | Splits (with addition of the new overtones) a given 'OvertonesO' into a number of 'OvertonesO' (represented finally as a 'V.Vector' of them repsectively) 
-- so that it intermediately uses a special function before applying the \"similarization\" splitting function. Is a generalization of the 'splitO', 
-- which can be considered a 'splitO2' with a first command line argument equals to 'id'.
-- 
-- It is expected to obtain by such a conversion a splitted one sound into several simultaneous similar (less or more, depending on @h :: OvertonesO -> OvertonesO@) 
-- ones with different heights. To provide a rich result, the given first argument must be strictly less than the length of the given 'OvertonesO' minus one.
splitO2 :: (OvertonesO -> OvertonesO) -> Int -> OvertonesO -> V.Vector OvertonesO
splitO2 :: (OvertonesO -> OvertonesO)
-> Int -> OvertonesO -> Vector OvertonesO
splitO2 OvertonesO -> OvertonesO
h Int
n OvertonesO
v0
 | Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (OvertonesO -> Int
forall a. Vector a -> Int
V.length OvertonesO
v0) (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
GT = 
    let v1 :: OvertonesO
v1 = [(Float, Float)] -> OvertonesO
forall a. [a] -> Vector a
V.fromList ([(Float, Float)] -> OvertonesO)
-> (OvertonesO -> [(Float, Float)]) -> OvertonesO -> OvertonesO
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Float, Float) -> (Float, Float) -> Ordering)
-> [(Float, Float)] -> [(Float, Float)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (\(Float
x1,Float
_) (Float
x2,Float
_) -> Float -> Float -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Float -> Float
forall a. Num a => a -> a
abs Float
x2) (Float -> Float
forall a. Num a => a -> a
abs Float
x1)) ([(Float, Float)] -> [(Float, Float)])
-> (OvertonesO -> [(Float, Float)])
-> OvertonesO
-> [(Float, Float)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OvertonesO -> [(Float, Float)]
forall a. Vector a -> [a]
V.toList (OvertonesO -> OvertonesO) -> OvertonesO -> OvertonesO
forall a b. (a -> b) -> a -> b
$ OvertonesO
v0
        (Float
x0, Float
y0) = OvertonesO -> Int -> (Float, Float)
forall a. Vector a -> Int -> a
V.unsafeIndex OvertonesO
v1 Int
0
        v2 :: OvertonesO
v2 = Int -> Int -> OvertonesO -> OvertonesO
forall a. Int -> Int -> Vector a -> Vector a
V.unsafeSlice Int
1 (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) OvertonesO
v1
        v31 :: Vector Float
v31 = ((Float, Float) -> Float) -> OvertonesO -> Vector Float
forall a b. (a -> b) -> Vector a -> Vector b
V.map (\(Float, Float)
t -> ((Float, Float) -> Float
forall a b. (a, b) -> a
fst (Float, Float)
t) Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
x0) OvertonesO
v2
        v32 :: Vector Float
v32 = ((Float, Float) -> Float) -> OvertonesO -> Vector Float
forall a b. (a -> b) -> Vector a -> Vector b
V.map (\(Float, Float)
t -> ((Float, Float) -> Float
forall a b. (a, b) -> b
snd (Float, Float)
t) Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
y0) OvertonesO
v2
        v3 :: OvertonesO
v3 = Vector Float -> Vector Float -> OvertonesO
forall a b. Vector a -> Vector b -> Vector (a, b)
V.zip Vector Float
v31 Vector Float
v32
        f1Tup :: (Float, Float) -> OvertonesO
f1Tup (Float
t1, Float
w2) = (Int -> (Float, Float) -> (Float, Float))
-> OvertonesO -> OvertonesO
forall a b. (Int -> a -> b) -> Vector a -> Vector b
V.imap (\ Int
i (Float, Float)
_ -> ((Float, Float) -> Float
forall a b. (a, b) -> a
fst (OvertonesO -> Int -> (Float, Float)
forall a. Vector a -> Int -> a
V.unsafeIndex OvertonesO
v3 Int
i) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
t1, (Float, Float) -> Float
forall a b. (a, b) -> b
snd (OvertonesO -> Int -> (Float, Float)
forall a. Vector a -> Int -> a
V.unsafeIndex OvertonesO
v3 Int
i) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
w2)) OvertonesO
v3
          in ((Float, Float) -> OvertonesO) -> OvertonesO -> Vector OvertonesO
forall a b. (a -> b) -> Vector a -> Vector b
V.map (Float, Float) -> OvertonesO
f1Tup (OvertonesO -> OvertonesO
h (OvertonesO -> OvertonesO)
-> (OvertonesO -> OvertonesO) -> OvertonesO -> OvertonesO
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Int -> OvertonesO -> OvertonesO
forall a. Int -> Int -> Vector a -> Vector a
V.unsafeSlice Int
0 Int
n (OvertonesO -> OvertonesO) -> OvertonesO -> OvertonesO
forall a b. (a -> b) -> a -> b
$ OvertonesO
v1)
 | Bool
otherwise = OvertonesO -> Vector OvertonesO
forall a. a -> Vector a
V.singleton OvertonesO
v0

-- | Generalized variant of the 'splitO' with the different splitting variants depending on the first two ASCII lower case letters in the 'String' argument.
splitOG1 :: String -> Int -> OvertonesO -> V.Vector OvertonesO
splitOG1 :: String -> Int -> OvertonesO -> Vector OvertonesO
splitOG1 String
xs Int
n OvertonesO
v0 
 | Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (OvertonesO -> Int
forall a. Vector a -> Int
V.length OvertonesO
v0) (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
GT = 
    let c1s :: String
c1s = Int -> String -> String
forall a. Int -> [a] -> [a]
take Int
2 (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
filter Char -> Bool
isAsciiLower (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String
xs
        v1 :: OvertonesO
v1 = [(Float, Float)] -> OvertonesO
forall a. [a] -> Vector a
V.fromList ([(Float, Float)] -> OvertonesO)
-> (OvertonesO -> [(Float, Float)]) -> OvertonesO -> OvertonesO
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Float, Float) -> (Float, Float) -> Ordering)
-> [(Float, Float)] -> [(Float, Float)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (\(Float
x1,Float
_) (Float
x2,Float
_) -> Float -> Float -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Float -> Float
forall a. Num a => a -> a
abs Float
x2) (Float -> Float
forall a. Num a => a -> a
abs Float
x1)) ([(Float, Float)] -> [(Float, Float)])
-> (OvertonesO -> [(Float, Float)])
-> OvertonesO
-> [(Float, Float)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OvertonesO -> [(Float, Float)]
forall a. Vector a -> [a]
V.toList (OvertonesO -> OvertonesO) -> OvertonesO -> OvertonesO
forall a b. (a -> b) -> a -> b
$ OvertonesO
v0
        (Float
x0, Float
y0) = OvertonesO -> Int -> (Float, Float)
forall a. Vector a -> Int -> a
V.unsafeIndex OvertonesO
v1 Int
0 in
          case String
c1s of
            String
"ab" -> let (Int
k1,Int
k2,Int
k3,Int
k4) = (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1,OvertonesO -> Int
forall a. Vector a -> Int
V.length OvertonesO
v0 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n,Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1,OvertonesO -> Int
forall a. Vector a -> Int
V.length OvertonesO
v0 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n) in Int
-> Int
-> Int
-> Int
-> OvertonesO
-> (Float, Float)
-> Vector OvertonesO
splitHelp1 Int
k1 Int
k2 Int
k3 Int
k4 OvertonesO
v1 (Float
x0,Float
y0) 
            String
"ac" -> let (Int
k1,Int
k2,Int
k3,Int
k4) = (Int
1,Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1,Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1,OvertonesO -> Int
forall a. Vector a -> Int
V.length OvertonesO
v0 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n) in Int
-> Int
-> Int
-> Int
-> OvertonesO
-> (Float, Float)
-> Vector OvertonesO
splitHelp1 Int
k1 Int
k2 Int
k3 Int
k4 OvertonesO
v1 (Float
x0,Float
y0) 
            String
"ad" -> let (Int
k1,Int
k2,Int
k3,Int
k4) = (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1,OvertonesO -> Int
forall a. Vector a -> Int
V.length OvertonesO
v0 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n,Int
0,Int
n) in Int
-> Int
-> Int
-> Int
-> OvertonesO
-> (Float, Float)
-> Vector OvertonesO
splitHelp1 Int
k1 Int
k2 Int
k3 Int
k4 OvertonesO
v1 (Float
x0,Float
y0) 
            String
_    -> let (Int
k1,Int
k2,Int
k3,Int
k4) = (Int
1,Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1,Int
0,Int
n) in Int
-> Int
-> Int
-> Int
-> OvertonesO
-> (Float, Float)
-> Vector OvertonesO
splitHelp1 Int
k1 Int
k2 Int
k3 Int
k4 OvertonesO
v1 (Float
x0,Float
y0) 
 | Bool
otherwise = OvertonesO -> Vector OvertonesO
forall a. a -> Vector a
V.singleton OvertonesO
v0

-- | Auxiliary function that is used inside 'splitOG1'.
splitHelp1 :: Int -> Int -> Int -> Int -> OvertonesO -> (Float,Float) -> V.Vector OvertonesO
splitHelp1 :: Int
-> Int
-> Int
-> Int
-> OvertonesO
-> (Float, Float)
-> Vector OvertonesO
splitHelp1 Int
x1 Int
x2 Int
x3 Int
x4 OvertonesO
v00 (Float
y5,Float
y6) = 
  let v2 :: OvertonesO
v2 = Int -> Int -> OvertonesO -> OvertonesO
forall a. Int -> Int -> Vector a -> Vector a
V.unsafeSlice Int
x1 Int
x2 OvertonesO
v00
      v31 :: Vector Float
v31 = ((Float, Float) -> Float) -> OvertonesO -> Vector Float
forall a b. (a -> b) -> Vector a -> Vector b
V.map (\(Float, Float)
t -> ((Float, Float) -> Float
forall a b. (a, b) -> a
fst (Float, Float)
t) Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
y5) OvertonesO
v2
      v32 :: Vector Float
v32 = ((Float, Float) -> Float) -> OvertonesO -> Vector Float
forall a b. (a -> b) -> Vector a -> Vector b
V.map (\(Float, Float)
t -> ((Float, Float) -> Float
forall a b. (a, b) -> b
snd (Float, Float)
t) Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
y6) OvertonesO
v2
      v3 :: OvertonesO
v3 = Vector Float -> Vector Float -> OvertonesO
forall a b. Vector a -> Vector b -> Vector (a, b)
V.zip Vector Float
v31 Vector Float
v32
      f1Tup :: (Float, Float) -> OvertonesO
f1Tup (Float
t1, Float
w2) = (Int -> (Float, Float) -> (Float, Float))
-> OvertonesO -> OvertonesO
forall a b. (Int -> a -> b) -> Vector a -> Vector b
V.imap (\ Int
i (Float, Float)
_ -> ((Float, Float) -> Float
forall a b. (a, b) -> a
fst (OvertonesO -> Int -> (Float, Float)
forall a. Vector a -> Int -> a
V.unsafeIndex OvertonesO
v3 Int
i) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
t1, (Float, Float) -> Float
forall a b. (a, b) -> b
snd (OvertonesO -> Int -> (Float, Float)
forall a. Vector a -> Int -> a
V.unsafeIndex OvertonesO
v3 Int
i) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
w2)) OvertonesO
v3
        in ((Float, Float) -> OvertonesO) -> OvertonesO -> Vector OvertonesO
forall a b. (a -> b) -> Vector a -> Vector b
V.map (Float, Float) -> OvertonesO
f1Tup (Int -> Int -> OvertonesO -> OvertonesO
forall a. Int -> Int -> Vector a -> Vector a
V.unsafeSlice Int
x3 Int
x4 OvertonesO
v00)

-- | Auxiliary function that is used inside 'splitOG2'.
splitHelp2 :: (OvertonesO -> OvertonesO) -> Int -> Int -> Int -> Int -> OvertonesO -> (Float,Float) -> V.Vector OvertonesO
splitHelp2 :: (OvertonesO -> OvertonesO)
-> Int
-> Int
-> Int
-> Int
-> OvertonesO
-> (Float, Float)
-> Vector OvertonesO
splitHelp2 OvertonesO -> OvertonesO
h1 Int
x1 Int
x2 Int
x3 Int
x4 OvertonesO
v00 (Float
y5,Float
y6) = 
  let v2 :: OvertonesO
v2 = Int -> Int -> OvertonesO -> OvertonesO
forall a. Int -> Int -> Vector a -> Vector a
V.unsafeSlice Int
x1 Int
x2 OvertonesO
v00
      v31 :: Vector Float
v31 = ((Float, Float) -> Float) -> OvertonesO -> Vector Float
forall a b. (a -> b) -> Vector a -> Vector b
V.map (\(Float, Float)
t -> ((Float, Float) -> Float
forall a b. (a, b) -> a
fst (Float, Float)
t) Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
y5) OvertonesO
v2
      v32 :: Vector Float
v32 = ((Float, Float) -> Float) -> OvertonesO -> Vector Float
forall a b. (a -> b) -> Vector a -> Vector b
V.map (\(Float, Float)
t -> ((Float, Float) -> Float
forall a b. (a, b) -> b
snd (Float, Float)
t) Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
y6) OvertonesO
v2
      v3 :: OvertonesO
v3 = Vector Float -> Vector Float -> OvertonesO
forall a b. Vector a -> Vector b -> Vector (a, b)
V.zip Vector Float
v31 Vector Float
v32
      f1Tup :: (Float, Float) -> OvertonesO
f1Tup (Float
t1, Float
w2) = (Int -> (Float, Float) -> (Float, Float))
-> OvertonesO -> OvertonesO
forall a b. (Int -> a -> b) -> Vector a -> Vector b
V.imap (\ Int
i (Float, Float)
_ -> ((Float, Float) -> Float
forall a b. (a, b) -> a
fst (OvertonesO -> Int -> (Float, Float)
forall a. Vector a -> Int -> a
V.unsafeIndex OvertonesO
v3 Int
i) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
t1, (Float, Float) -> Float
forall a b. (a, b) -> b
snd (OvertonesO -> Int -> (Float, Float)
forall a. Vector a -> Int -> a
V.unsafeIndex OvertonesO
v3 Int
i) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
w2)) OvertonesO
v3
        in ((Float, Float) -> OvertonesO) -> OvertonesO -> Vector OvertonesO
forall a b. (a -> b) -> Vector a -> Vector b
V.map (Float, Float) -> OvertonesO
f1Tup (OvertonesO -> OvertonesO
h1 (OvertonesO -> OvertonesO)
-> (OvertonesO -> OvertonesO) -> OvertonesO -> OvertonesO
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Int -> OvertonesO -> OvertonesO
forall a. Int -> Int -> Vector a -> Vector a
V.unsafeSlice Int
x3 Int
x4 (OvertonesO -> OvertonesO) -> OvertonesO -> OvertonesO
forall a b. (a -> b) -> a -> b
$ OvertonesO
v00)        

-- | Generalized variant of the 'splitO2' with the different splitting variants depending on the first two ASCII lower case letters in the 'String' argument.
splitOG2 :: (OvertonesO -> OvertonesO) -> String -> Int -> OvertonesO -> V.Vector OvertonesO
splitOG2 :: (OvertonesO -> OvertonesO)
-> String -> Int -> OvertonesO -> Vector OvertonesO
splitOG2 OvertonesO -> OvertonesO
h String
xs Int
n OvertonesO
v0
 | Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (OvertonesO -> Int
forall a. Vector a -> Int
V.length OvertonesO
v0) (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
GT = 
    let c1s :: String
c1s = Int -> String -> String
forall a. Int -> [a] -> [a]
take Int
2 (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
filter Char -> Bool
isAsciiLower (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String
xs
        v1 :: OvertonesO
v1 = [(Float, Float)] -> OvertonesO
forall a. [a] -> Vector a
V.fromList ([(Float, Float)] -> OvertonesO)
-> (OvertonesO -> [(Float, Float)]) -> OvertonesO -> OvertonesO
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Float, Float) -> (Float, Float) -> Ordering)
-> [(Float, Float)] -> [(Float, Float)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (\(Float
x1,Float
_) (Float
x2,Float
_) -> Float -> Float -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Float -> Float
forall a. Num a => a -> a
abs Float
x2) (Float -> Float
forall a. Num a => a -> a
abs Float
x1)) ([(Float, Float)] -> [(Float, Float)])
-> (OvertonesO -> [(Float, Float)])
-> OvertonesO
-> [(Float, Float)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OvertonesO -> [(Float, Float)]
forall a. Vector a -> [a]
V.toList (OvertonesO -> OvertonesO) -> OvertonesO -> OvertonesO
forall a b. (a -> b) -> a -> b
$ OvertonesO
v0
        (Float
x0, Float
y0) = OvertonesO -> Int -> (Float, Float)
forall a. Vector a -> Int -> a
V.unsafeIndex OvertonesO
v1 Int
0 in
          case String
c1s of
            String
"ab" -> let (Int
k1,Int
k2,Int
k3,Int
k4) = (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1,OvertonesO -> Int
forall a. Vector a -> Int
V.length OvertonesO
v0 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n,Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1,OvertonesO -> Int
forall a. Vector a -> Int
V.length OvertonesO
v0 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n) in (OvertonesO -> OvertonesO)
-> Int
-> Int
-> Int
-> Int
-> OvertonesO
-> (Float, Float)
-> Vector OvertonesO
splitHelp2 OvertonesO -> OvertonesO
h Int
k1 Int
k2 Int
k3 Int
k4 OvertonesO
v1 (Float
x0,Float
y0) 
            String
"ac" -> let (Int
k1,Int
k2,Int
k3,Int
k4) = (Int
1,Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1,Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1,OvertonesO -> Int
forall a. Vector a -> Int
V.length OvertonesO
v0 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n) in (OvertonesO -> OvertonesO)
-> Int
-> Int
-> Int
-> Int
-> OvertonesO
-> (Float, Float)
-> Vector OvertonesO
splitHelp2 OvertonesO -> OvertonesO
h Int
k1 Int
k2 Int
k3 Int
k4 OvertonesO
v1 (Float
x0,Float
y0) 
            String
"ad" -> let (Int
k1,Int
k2,Int
k3,Int
k4) = (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1,OvertonesO -> Int
forall a. Vector a -> Int
V.length OvertonesO
v0 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n,Int
0,Int
n) in (OvertonesO -> OvertonesO)
-> Int
-> Int
-> Int
-> Int
-> OvertonesO
-> (Float, Float)
-> Vector OvertonesO
splitHelp2 OvertonesO -> OvertonesO
h Int
k1 Int
k2 Int
k3 Int
k4 OvertonesO
v1 (Float
x0,Float
y0) 
            String
_    -> let (Int
k1,Int
k2,Int
k3,Int
k4) = (Int
1,Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1,Int
0,Int
n) in (OvertonesO -> OvertonesO)
-> Int
-> Int
-> Int
-> Int
-> OvertonesO
-> (Float, Float)
-> Vector OvertonesO
splitHelp2 OvertonesO -> OvertonesO
h Int
k1 Int
k2 Int
k3 Int
k4 OvertonesO
v1 (Float
x0,Float
y0) 
 | Bool
otherwise = OvertonesO -> Vector OvertonesO
forall a. a -> Vector a
V.singleton OvertonesO
v0    

-- | Generalized variant of the 'splitOG1' with a possibility to specify a default value for splitting parameters as the first argument 
-- @(Int,Int,Int,Int)@ and the sorted by the first element in the tuple (actually a 'String') in ascending order 'V.Vector' (the second one). 
-- Each 'String' in the 'V.Vector' must be unique and consist of lowercase ASCII letters.
splitOG12 :: (Int,Int,Int,Int) -> V.Vector (String,Int -> OvertonesO -> (Int,Int,Int,Int)) -> String -> Int -> OvertonesO -> V.Vector OvertonesO
splitOG12 :: (Int, Int, Int, Int)
-> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
-> String
-> Int
-> OvertonesO
-> Vector OvertonesO
splitOG12 (Int
x1,Int
x2,Int
x3,Int
x4) Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
vf String
xs Int
n OvertonesO
v0
 | Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (OvertonesO -> Int
forall a. Vector a -> Int
V.length OvertonesO
v0) (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
GT Bool -> Bool -> Bool
&& Bool -> Bool
not (Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int)) -> Bool
forall a. Vector a -> Bool
V.null Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
vf) = 
    let c1s :: String
c1s = (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
filter Char -> Bool
isAsciiLower (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String
xs
        v1 :: OvertonesO
v1 = [(Float, Float)] -> OvertonesO
forall a. [a] -> Vector a
V.fromList ([(Float, Float)] -> OvertonesO)
-> (OvertonesO -> [(Float, Float)]) -> OvertonesO -> OvertonesO
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Float, Float) -> (Float, Float) -> Ordering)
-> [(Float, Float)] -> [(Float, Float)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (\(Float
x1,Float
_) (Float
x2,Float
_) -> Float -> Float -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Float -> Float
forall a. Num a => a -> a
abs Float
x2) (Float -> Float
forall a. Num a => a -> a
abs Float
x1)) ([(Float, Float)] -> [(Float, Float)])
-> (OvertonesO -> [(Float, Float)])
-> OvertonesO
-> [(Float, Float)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OvertonesO -> [(Float, Float)]
forall a. Vector a -> [a]
V.toList (OvertonesO -> OvertonesO) -> OvertonesO -> OvertonesO
forall a b. (a -> b) -> a -> b
$ OvertonesO
v0
        (Float
x0, Float
y0) = OvertonesO -> Int -> (Float, Float)
forall a. Vector a -> Int -> a
V.unsafeIndex OvertonesO
v1 Int
0 in let (Int
k1,Int
k2,Int
k3,Int
k4) = (Int, Int, Int, Int)
-> [(String, (Int, Int, Int, Int))]
-> String
-> (Int, Int, Int, Int)
forall a b. Ord a => b -> [(a, b)] -> a -> b
getBFstLSorted' (Int
x1,Int
x2,Int
x3,Int
x4) (Vector (String, (Int, Int, Int, Int))
-> [(String, (Int, Int, Int, Int))]
forall a. Vector a -> [a]
V.toList (Vector (String, (Int, Int, Int, Int))
 -> [(String, (Int, Int, Int, Int))])
-> (Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
    -> Vector (String, (Int, Int, Int, Int)))
-> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
-> [(String, (Int, Int, Int, Int))]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String, Int -> OvertonesO -> (Int, Int, Int, Int))
 -> (String, (Int, Int, Int, Int)))
-> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
-> Vector (String, (Int, Int, Int, Int))
forall a b. (a -> b) -> Vector a -> Vector b
V.map (\(String
ys,Int -> OvertonesO -> (Int, Int, Int, Int)
g) -> (String
ys,Int -> OvertonesO -> (Int, Int, Int, Int)
g Int
n OvertonesO
v1)) (Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
 -> [(String, (Int, Int, Int, Int))])
-> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
-> [(String, (Int, Int, Int, Int))]
forall a b. (a -> b) -> a -> b
$ Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
vf) String
c1s in 
          Int
-> Int
-> Int
-> Int
-> OvertonesO
-> (Float, Float)
-> Vector OvertonesO
splitHelp1 Int
k1 Int
k2 Int
k3 Int
k4 OvertonesO
v1 (Float
x0,Float
y0) 
 | Bool
otherwise = OvertonesO -> Vector OvertonesO
forall a. a -> Vector a
V.singleton OvertonesO
v0    

-- | Variant of the 'splitOG12' applied to the unsorted second argument. It sorts it internally. If you specify the already sorted second argument 
-- then it is better to use 'splitOG12'. Each 'String' in the 'V.Vector' must be unique and consist of lowercase ASCII letters.
splitOG12S :: (Int,Int,Int,Int) -> V.Vector (String,Int -> OvertonesO -> (Int,Int,Int,Int)) -> String -> Int -> OvertonesO -> V.Vector OvertonesO
splitOG12S :: (Int, Int, Int, Int)
-> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
-> String
-> Int
-> OvertonesO
-> Vector OvertonesO
splitOG12S (Int
x1,Int
x2,Int
x3,Int
x4) Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
vf String
xs Int
n OvertonesO
v0
 | Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (OvertonesO -> Int
forall a. Vector a -> Int
V.length OvertonesO
v0) (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
GT Bool -> Bool -> Bool
&& Bool -> Bool
not (Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int)) -> Bool
forall a. Vector a -> Bool
V.null Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
vf) = 
    let c1s :: String
c1s = (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
filter Char -> Bool
isAsciiLower (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String
xs
        v1 :: OvertonesO
v1 = [(Float, Float)] -> OvertonesO
forall a. [a] -> Vector a
V.fromList ([(Float, Float)] -> OvertonesO)
-> (OvertonesO -> [(Float, Float)]) -> OvertonesO -> OvertonesO
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Float, Float) -> (Float, Float) -> Ordering)
-> [(Float, Float)] -> [(Float, Float)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (\(Float
x1,Float
_) (Float
x2,Float
_) -> Float -> Float -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Float -> Float
forall a. Num a => a -> a
abs Float
x2) (Float -> Float
forall a. Num a => a -> a
abs Float
x1)) ([(Float, Float)] -> [(Float, Float)])
-> (OvertonesO -> [(Float, Float)])
-> OvertonesO
-> [(Float, Float)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OvertonesO -> [(Float, Float)]
forall a. Vector a -> [a]
V.toList (OvertonesO -> OvertonesO) -> OvertonesO -> OvertonesO
forall a b. (a -> b) -> a -> b
$ OvertonesO
v0
        v2 :: Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
v2 = [(String, Int -> OvertonesO -> (Int, Int, Int, Int))]
-> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
forall a. [a] -> Vector a
V.fromList ([(String, Int -> OvertonesO -> (Int, Int, Int, Int))]
 -> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int)))
-> (Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
    -> [(String, Int -> OvertonesO -> (Int, Int, Int, Int))])
-> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
-> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String, Int -> OvertonesO -> (Int, Int, Int, Int))
 -> (String, Int -> OvertonesO -> (Int, Int, Int, Int)) -> Ordering)
-> [(String, Int -> OvertonesO -> (Int, Int, Int, Int))]
-> [(String, Int -> OvertonesO -> (Int, Int, Int, Int))]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (\(String
x1s,Int -> OvertonesO -> (Int, Int, Int, Int)
_) (String
x2s,Int -> OvertonesO -> (Int, Int, Int, Int)
_) -> String -> String -> Ordering
forall a. Ord a => a -> a -> Ordering
compare String
x1s String
x2s) ([(String, Int -> OvertonesO -> (Int, Int, Int, Int))]
 -> [(String, Int -> OvertonesO -> (Int, Int, Int, Int))])
-> (Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
    -> [(String, Int -> OvertonesO -> (Int, Int, Int, Int))])
-> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
-> [(String, Int -> OvertonesO -> (Int, Int, Int, Int))]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
-> [(String, Int -> OvertonesO -> (Int, Int, Int, Int))]
forall a. Vector a -> [a]
V.toList (Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
 -> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int)))
-> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
-> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
forall a b. (a -> b) -> a -> b
$ Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
vf
        (Float
x0, Float
y0) = OvertonesO -> Int -> (Float, Float)
forall a. Vector a -> Int -> a
V.unsafeIndex OvertonesO
v1 Int
0 in let (Int
k1,Int
k2,Int
k3,Int
k4) = (Int, Int, Int, Int)
-> [(String, (Int, Int, Int, Int))]
-> String
-> (Int, Int, Int, Int)
forall a b. Ord a => b -> [(a, b)] -> a -> b
getBFstLSorted' (Int
x1,Int
x2,Int
x3,Int
x4) (Vector (String, (Int, Int, Int, Int))
-> [(String, (Int, Int, Int, Int))]
forall a. Vector a -> [a]
V.toList (Vector (String, (Int, Int, Int, Int))
 -> [(String, (Int, Int, Int, Int))])
-> (Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
    -> Vector (String, (Int, Int, Int, Int)))
-> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
-> [(String, (Int, Int, Int, Int))]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String, Int -> OvertonesO -> (Int, Int, Int, Int))
 -> (String, (Int, Int, Int, Int)))
-> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
-> Vector (String, (Int, Int, Int, Int))
forall a b. (a -> b) -> Vector a -> Vector b
V.map (\(String
ys,Int -> OvertonesO -> (Int, Int, Int, Int)
g) -> (String
ys,Int -> OvertonesO -> (Int, Int, Int, Int)
g Int
n OvertonesO
v1)) (Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
 -> [(String, (Int, Int, Int, Int))])
-> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
-> [(String, (Int, Int, Int, Int))]
forall a b. (a -> b) -> a -> b
$ Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
v2) String
c1s in 
          Int
-> Int
-> Int
-> Int
-> OvertonesO
-> (Float, Float)
-> Vector OvertonesO
splitHelp1 Int
k1 Int
k2 Int
k3 Int
k4 OvertonesO
v1 (Float
x0,Float
y0) 
 | Bool
otherwise = OvertonesO -> Vector OvertonesO
forall a. a -> Vector a
V.singleton OvertonesO
v0    

-- | Generalized variant of the 'splitOG2' with a possibility to specify a default value for splitting parameters as the first argument 
-- @(Int,Int,Int,Int)@ and the sorted by the first element in the tuple (actually a 'String') in ascending order 'V.Vector' (the second one). 
-- Each 'String' in the 'V.Vector' must be unique and consist of lowercase ASCII letters.
splitOG22 :: (Int,Int,Int,Int) -> V.Vector (String,Int -> OvertonesO -> (Int,Int,Int,Int)) -> (OvertonesO -> OvertonesO) -> String -> Int -> 
  OvertonesO -> V.Vector OvertonesO
splitOG22 :: (Int, Int, Int, Int)
-> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
-> (OvertonesO -> OvertonesO)
-> String
-> Int
-> OvertonesO
-> Vector OvertonesO
splitOG22 (Int
x1,Int
x2,Int
x3,Int
x4) Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
vf OvertonesO -> OvertonesO
h String
xs Int
n OvertonesO
v0
 | Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (OvertonesO -> Int
forall a. Vector a -> Int
V.length OvertonesO
v0) (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
GT Bool -> Bool -> Bool
&& Bool -> Bool
not (Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int)) -> Bool
forall a. Vector a -> Bool
V.null Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
vf) = 
    let c1s :: String
c1s = (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
filter Char -> Bool
isAsciiLower (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String
xs
        v1 :: OvertonesO
v1 = [(Float, Float)] -> OvertonesO
forall a. [a] -> Vector a
V.fromList ([(Float, Float)] -> OvertonesO)
-> (OvertonesO -> [(Float, Float)]) -> OvertonesO -> OvertonesO
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Float, Float) -> (Float, Float) -> Ordering)
-> [(Float, Float)] -> [(Float, Float)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (\(Float
x1,Float
_) (Float
x2,Float
_) -> Float -> Float -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Float -> Float
forall a. Num a => a -> a
abs Float
x2) (Float -> Float
forall a. Num a => a -> a
abs Float
x1)) ([(Float, Float)] -> [(Float, Float)])
-> (OvertonesO -> [(Float, Float)])
-> OvertonesO
-> [(Float, Float)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OvertonesO -> [(Float, Float)]
forall a. Vector a -> [a]
V.toList (OvertonesO -> OvertonesO) -> OvertonesO -> OvertonesO
forall a b. (a -> b) -> a -> b
$ OvertonesO
v0
        (Float
x0, Float
y0) = OvertonesO -> Int -> (Float, Float)
forall a. Vector a -> Int -> a
V.unsafeIndex OvertonesO
v1 Int
0 in let (Int
k1,Int
k2,Int
k3,Int
k4) = (Int, Int, Int, Int)
-> [(String, (Int, Int, Int, Int))]
-> String
-> (Int, Int, Int, Int)
forall a b. Ord a => b -> [(a, b)] -> a -> b
getBFstLSorted' (Int
x1,Int
x2,Int
x3,Int
x4) (Vector (String, (Int, Int, Int, Int))
-> [(String, (Int, Int, Int, Int))]
forall a. Vector a -> [a]
V.toList (Vector (String, (Int, Int, Int, Int))
 -> [(String, (Int, Int, Int, Int))])
-> (Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
    -> Vector (String, (Int, Int, Int, Int)))
-> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
-> [(String, (Int, Int, Int, Int))]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String, Int -> OvertonesO -> (Int, Int, Int, Int))
 -> (String, (Int, Int, Int, Int)))
-> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
-> Vector (String, (Int, Int, Int, Int))
forall a b. (a -> b) -> Vector a -> Vector b
V.map (\(String
ys,Int -> OvertonesO -> (Int, Int, Int, Int)
g) -> (String
ys,Int -> OvertonesO -> (Int, Int, Int, Int)
g Int
n OvertonesO
v1)) (Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
 -> [(String, (Int, Int, Int, Int))])
-> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
-> [(String, (Int, Int, Int, Int))]
forall a b. (a -> b) -> a -> b
$ Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
vf) String
c1s in 
          (OvertonesO -> OvertonesO)
-> Int
-> Int
-> Int
-> Int
-> OvertonesO
-> (Float, Float)
-> Vector OvertonesO
splitHelp2 OvertonesO -> OvertonesO
h Int
k1 Int
k2 Int
k3 Int
k4 OvertonesO
v1 (Float
x0,Float
y0) 
 | Bool
otherwise = OvertonesO -> Vector OvertonesO
forall a. a -> Vector a
V.singleton OvertonesO
v0    
 
-- | Variant of the 'splitOG22' applied to the unsorted second argument. It sorts it internally. If you specify the already sorted second argument 
-- then it is better to use 'splitOG22'. Each 'String' in the 'V.Vector' must be unique and consist of lowercase ASCII letters.
splitOG22S :: (Int,Int,Int,Int) -> V.Vector (String,Int -> OvertonesO -> (Int,Int,Int,Int)) -> (OvertonesO -> OvertonesO) -> String -> Int -> 
  OvertonesO -> V.Vector OvertonesO
splitOG22S :: (Int, Int, Int, Int)
-> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
-> (OvertonesO -> OvertonesO)
-> String
-> Int
-> OvertonesO
-> Vector OvertonesO
splitOG22S (Int
x1,Int
x2,Int
x3,Int
x4) Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
vf OvertonesO -> OvertonesO
h String
xs Int
n OvertonesO
v0
 | Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (OvertonesO -> Int
forall a. Vector a -> Int
V.length OvertonesO
v0) (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
GT Bool -> Bool -> Bool
&& Bool -> Bool
not (Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int)) -> Bool
forall a. Vector a -> Bool
V.null Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
vf) = 
    let c1s :: String
c1s = (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
filter Char -> Bool
isAsciiLower (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String
xs
        v1 :: OvertonesO
v1 = [(Float, Float)] -> OvertonesO
forall a. [a] -> Vector a
V.fromList ([(Float, Float)] -> OvertonesO)
-> (OvertonesO -> [(Float, Float)]) -> OvertonesO -> OvertonesO
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Float, Float) -> (Float, Float) -> Ordering)
-> [(Float, Float)] -> [(Float, Float)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (\(Float
x1,Float
_) (Float
x2,Float
_) -> Float -> Float -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Float -> Float
forall a. Num a => a -> a
abs Float
x2) (Float -> Float
forall a. Num a => a -> a
abs Float
x1)) ([(Float, Float)] -> [(Float, Float)])
-> (OvertonesO -> [(Float, Float)])
-> OvertonesO
-> [(Float, Float)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OvertonesO -> [(Float, Float)]
forall a. Vector a -> [a]
V.toList (OvertonesO -> OvertonesO) -> OvertonesO -> OvertonesO
forall a b. (a -> b) -> a -> b
$ OvertonesO
v0
        v2 :: Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
v2 = [(String, Int -> OvertonesO -> (Int, Int, Int, Int))]
-> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
forall a. [a] -> Vector a
V.fromList ([(String, Int -> OvertonesO -> (Int, Int, Int, Int))]
 -> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int)))
-> (Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
    -> [(String, Int -> OvertonesO -> (Int, Int, Int, Int))])
-> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
-> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String, Int -> OvertonesO -> (Int, Int, Int, Int))
 -> (String, Int -> OvertonesO -> (Int, Int, Int, Int)) -> Ordering)
-> [(String, Int -> OvertonesO -> (Int, Int, Int, Int))]
-> [(String, Int -> OvertonesO -> (Int, Int, Int, Int))]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (\(String
x1s,Int -> OvertonesO -> (Int, Int, Int, Int)
_) (String
x2s,Int -> OvertonesO -> (Int, Int, Int, Int)
_) -> String -> String -> Ordering
forall a. Ord a => a -> a -> Ordering
compare String
x1s String
x2s) ([(String, Int -> OvertonesO -> (Int, Int, Int, Int))]
 -> [(String, Int -> OvertonesO -> (Int, Int, Int, Int))])
-> (Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
    -> [(String, Int -> OvertonesO -> (Int, Int, Int, Int))])
-> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
-> [(String, Int -> OvertonesO -> (Int, Int, Int, Int))]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
-> [(String, Int -> OvertonesO -> (Int, Int, Int, Int))]
forall a. Vector a -> [a]
V.toList (Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
 -> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int)))
-> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
-> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
forall a b. (a -> b) -> a -> b
$ Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
vf
        (Float
x0, Float
y0) = OvertonesO -> Int -> (Float, Float)
forall a. Vector a -> Int -> a
V.unsafeIndex OvertonesO
v1 Int
0 in let (Int
k1,Int
k2,Int
k3,Int
k4) = (Int, Int, Int, Int)
-> [(String, (Int, Int, Int, Int))]
-> String
-> (Int, Int, Int, Int)
forall a b. Ord a => b -> [(a, b)] -> a -> b
getBFstLSorted' (Int
x1,Int
x2,Int
x3,Int
x4) (Vector (String, (Int, Int, Int, Int))
-> [(String, (Int, Int, Int, Int))]
forall a. Vector a -> [a]
V.toList (Vector (String, (Int, Int, Int, Int))
 -> [(String, (Int, Int, Int, Int))])
-> (Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
    -> Vector (String, (Int, Int, Int, Int)))
-> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
-> [(String, (Int, Int, Int, Int))]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String, Int -> OvertonesO -> (Int, Int, Int, Int))
 -> (String, (Int, Int, Int, Int)))
-> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
-> Vector (String, (Int, Int, Int, Int))
forall a b. (a -> b) -> Vector a -> Vector b
V.map (\(String
ys,Int -> OvertonesO -> (Int, Int, Int, Int)
g) -> (String
ys,Int -> OvertonesO -> (Int, Int, Int, Int)
g Int
n OvertonesO
v1)) (Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
 -> [(String, (Int, Int, Int, Int))])
-> Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
-> [(String, (Int, Int, Int, Int))]
forall a b. (a -> b) -> a -> b
$ Vector (String, Int -> OvertonesO -> (Int, Int, Int, Int))
v2) String
c1s in 
          (OvertonesO -> OvertonesO)
-> Int
-> Int
-> Int
-> Int
-> OvertonesO
-> (Float, Float)
-> Vector OvertonesO
splitHelp2 OvertonesO -> OvertonesO
h Int
k1 Int
k2 Int
k3 Int
k4 OvertonesO
v1 (Float
x0,Float
y0) 
 | Bool
otherwise = OvertonesO -> Vector OvertonesO
forall a. a -> Vector a
V.singleton OvertonesO
v0    

-- | Concatenates a 'V.Vector' of 'OvertonesO' into a single 'OvertonesO'. Can be easily used with 'splitO'.
overConcat :: V.Vector OvertonesO -> OvertonesO
overConcat :: Vector OvertonesO -> OvertonesO
overConcat = [OvertonesO] -> OvertonesO
forall a. [Vector a] -> Vector a
V.concat ([OvertonesO] -> OvertonesO)
-> (Vector OvertonesO -> [OvertonesO])
-> Vector OvertonesO
-> OvertonesO
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector OvertonesO -> [OvertonesO]
forall a. Vector a -> [a]
V.toList