module Harmonic.Rules.Types.ProgressionContext
( Layer(..)
, Family(..)
, ProgressionContext(..)
, layer
, pcLength
, fromProgression
, liftPC
, liftPCAligned
, liftPCSubst
, normalizeFamily
, pcSplice
) where
import Data.Sequence (Seq, (><))
import qualified Data.Sequence as Seq
import Data.Foldable (toList)
import Data.List (transpose)
import qualified Harmonic.Rules.Types.Progression as Prog
import Harmonic.Rules.Types.Progression (Progression(..), progLength)
import qualified Harmonic.Rules.Types.Harmony as H
import qualified Harmonic.Rules.Types.Pitch as P
import Harmonic.Rules.Types.Scale (Tristrata, StrataLabel)
data Layer = T | S | M | TS | TM | SM | TSM | PT
deriving (Layer -> Layer -> Bool
(Layer -> Layer -> Bool) -> (Layer -> Layer -> Bool) -> Eq Layer
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Layer -> Layer -> Bool
== :: Layer -> Layer -> Bool
$c/= :: Layer -> Layer -> Bool
/= :: Layer -> Layer -> Bool
Eq, Eq Layer
Eq Layer =>
(Layer -> Layer -> Ordering)
-> (Layer -> Layer -> Bool)
-> (Layer -> Layer -> Bool)
-> (Layer -> Layer -> Bool)
-> (Layer -> Layer -> Bool)
-> (Layer -> Layer -> Layer)
-> (Layer -> Layer -> Layer)
-> Ord Layer
Layer -> Layer -> Bool
Layer -> Layer -> Ordering
Layer -> Layer -> Layer
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Layer -> Layer -> Ordering
compare :: Layer -> Layer -> Ordering
$c< :: Layer -> Layer -> Bool
< :: Layer -> Layer -> Bool
$c<= :: Layer -> Layer -> Bool
<= :: Layer -> Layer -> Bool
$c> :: Layer -> Layer -> Bool
> :: Layer -> Layer -> Bool
$c>= :: Layer -> Layer -> Bool
>= :: Layer -> Layer -> Bool
$cmax :: Layer -> Layer -> Layer
max :: Layer -> Layer -> Layer
$cmin :: Layer -> Layer -> Layer
min :: Layer -> Layer -> Layer
Ord, Int -> Layer -> ShowS
[Layer] -> ShowS
Layer -> String
(Int -> Layer -> ShowS)
-> (Layer -> String) -> ([Layer] -> ShowS) -> Show Layer
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Layer -> ShowS
showsPrec :: Int -> Layer -> ShowS
$cshow :: Layer -> String
show :: Layer -> String
$cshowList :: [Layer] -> ShowS
showList :: [Layer] -> ShowS
Show, ReadPrec [Layer]
ReadPrec Layer
Int -> ReadS Layer
ReadS [Layer]
(Int -> ReadS Layer)
-> ReadS [Layer]
-> ReadPrec Layer
-> ReadPrec [Layer]
-> Read Layer
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Layer
readsPrec :: Int -> ReadS Layer
$creadList :: ReadS [Layer]
readList :: ReadS [Layer]
$creadPrec :: ReadPrec Layer
readPrec :: ReadPrec Layer
$creadListPrec :: ReadPrec [Layer]
readListPrec :: ReadPrec [Layer]
Read, Int -> Layer
Layer -> Int
Layer -> [Layer]
Layer -> Layer
Layer -> Layer -> [Layer]
Layer -> Layer -> Layer -> [Layer]
(Layer -> Layer)
-> (Layer -> Layer)
-> (Int -> Layer)
-> (Layer -> Int)
-> (Layer -> [Layer])
-> (Layer -> Layer -> [Layer])
-> (Layer -> Layer -> [Layer])
-> (Layer -> Layer -> Layer -> [Layer])
-> Enum Layer
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: Layer -> Layer
succ :: Layer -> Layer
$cpred :: Layer -> Layer
pred :: Layer -> Layer
$ctoEnum :: Int -> Layer
toEnum :: Int -> Layer
$cfromEnum :: Layer -> Int
fromEnum :: Layer -> Int
$cenumFrom :: Layer -> [Layer]
enumFrom :: Layer -> [Layer]
$cenumFromThen :: Layer -> Layer -> [Layer]
enumFromThen :: Layer -> Layer -> [Layer]
$cenumFromTo :: Layer -> Layer -> [Layer]
enumFromTo :: Layer -> Layer -> [Layer]
$cenumFromThenTo :: Layer -> Layer -> Layer -> [Layer]
enumFromThenTo :: Layer -> Layer -> Layer -> [Layer]
Enum, Layer
Layer -> Layer -> Bounded Layer
forall a. a -> a -> Bounded a
$cminBound :: Layer
minBound :: Layer
$cmaxBound :: Layer
maxBound :: Layer
Bounded)
data Family = FTriad | FExtended | FStrata | FJazz | FPoly
deriving (Family -> Family -> Bool
(Family -> Family -> Bool)
-> (Family -> Family -> Bool) -> Eq Family
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Family -> Family -> Bool
== :: Family -> Family -> Bool
$c/= :: Family -> Family -> Bool
/= :: Family -> Family -> Bool
Eq, Eq Family
Eq Family =>
(Family -> Family -> Ordering)
-> (Family -> Family -> Bool)
-> (Family -> Family -> Bool)
-> (Family -> Family -> Bool)
-> (Family -> Family -> Bool)
-> (Family -> Family -> Family)
-> (Family -> Family -> Family)
-> Ord Family
Family -> Family -> Bool
Family -> Family -> Ordering
Family -> Family -> Family
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Family -> Family -> Ordering
compare :: Family -> Family -> Ordering
$c< :: Family -> Family -> Bool
< :: Family -> Family -> Bool
$c<= :: Family -> Family -> Bool
<= :: Family -> Family -> Bool
$c> :: Family -> Family -> Bool
> :: Family -> Family -> Bool
$c>= :: Family -> Family -> Bool
>= :: Family -> Family -> Bool
$cmax :: Family -> Family -> Family
max :: Family -> Family -> Family
$cmin :: Family -> Family -> Family
min :: Family -> Family -> Family
Ord, Int -> Family -> ShowS
[Family] -> ShowS
Family -> String
(Int -> Family -> ShowS)
-> (Family -> String) -> ([Family] -> ShowS) -> Show Family
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Family -> ShowS
showsPrec :: Int -> Family -> ShowS
$cshow :: Family -> String
show :: Family -> String
$cshowList :: [Family] -> ShowS
showList :: [Family] -> ShowS
Show, ReadPrec [Family]
ReadPrec Family
Int -> ReadS Family
ReadS [Family]
(Int -> ReadS Family)
-> ReadS [Family]
-> ReadPrec Family
-> ReadPrec [Family]
-> Read Family
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Family
readsPrec :: Int -> ReadS Family
$creadList :: ReadS [Family]
readList :: ReadS [Family]
$creadPrec :: ReadPrec Family
readPrec :: ReadPrec Family
$creadListPrec :: ReadPrec [Family]
readListPrec :: ReadPrec [Family]
Read, Int -> Family
Family -> Int
Family -> [Family]
Family -> Family
Family -> Family -> [Family]
Family -> Family -> Family -> [Family]
(Family -> Family)
-> (Family -> Family)
-> (Int -> Family)
-> (Family -> Int)
-> (Family -> [Family])
-> (Family -> Family -> [Family])
-> (Family -> Family -> [Family])
-> (Family -> Family -> Family -> [Family])
-> Enum Family
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: Family -> Family
succ :: Family -> Family
$cpred :: Family -> Family
pred :: Family -> Family
$ctoEnum :: Int -> Family
toEnum :: Int -> Family
$cfromEnum :: Family -> Int
fromEnum :: Family -> Int
$cenumFrom :: Family -> [Family]
enumFrom :: Family -> [Family]
$cenumFromThen :: Family -> Family -> [Family]
enumFromThen :: Family -> Family -> [Family]
$cenumFromTo :: Family -> Family -> [Family]
enumFromTo :: Family -> Family -> [Family]
$cenumFromThenTo :: Family -> Family -> Family -> [Family]
enumFromThenTo :: Family -> Family -> Family -> [Family]
Enum, Family
Family -> Family -> Bounded Family
forall a. a -> a -> Bounded a
$cminBound :: Family
minBound :: Family
$cmaxBound :: Family
maxBound :: Family
Bounded)
data ProgressionContext = ProgressionContext
{ ProgressionContext -> Progression
triadLayer :: Progression
, ProgressionContext -> Progression
strataLayer :: Progression
, ProgressionContext -> Progression
modeLayer :: Progression
, ProgressionContext -> Maybe (Seq (Tristrata, StrataLabel))
pcProvenance :: Maybe (Seq (Tristrata, StrataLabel))
, ProgressionContext -> Family
pcFamily :: Family
} deriving (ProgressionContext -> ProgressionContext -> Bool
(ProgressionContext -> ProgressionContext -> Bool)
-> (ProgressionContext -> ProgressionContext -> Bool)
-> Eq ProgressionContext
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ProgressionContext -> ProgressionContext -> Bool
== :: ProgressionContext -> ProgressionContext -> Bool
$c/= :: ProgressionContext -> ProgressionContext -> Bool
/= :: ProgressionContext -> ProgressionContext -> Bool
Eq)
instance Show ProgressionContext where
show :: ProgressionContext -> String
show = Progression -> String
forall a. Show a => a -> String
show (Progression -> String)
-> (ProgressionContext -> Progression)
-> ProgressionContext
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProgressionContext -> Progression
triadLayer
layer :: Layer -> ProgressionContext -> Progression
layer :: Layer -> ProgressionContext -> Progression
layer Layer
T = ProgressionContext -> Progression
triadLayer
layer Layer
S = ProgressionContext -> Progression
strataLayer
layer Layer
M = ProgressionContext -> Progression
modeLayer
layer Layer
TS = [ProgressionContext -> Progression]
-> ProgressionContext -> Progression
mergeLayers [ProgressionContext -> Progression
triadLayer, ProgressionContext -> Progression
strataLayer]
layer Layer
TM = [ProgressionContext -> Progression]
-> ProgressionContext -> Progression
mergeLayers [ProgressionContext -> Progression
triadLayer, ProgressionContext -> Progression
modeLayer]
layer Layer
SM = [ProgressionContext -> Progression]
-> ProgressionContext -> Progression
mergeLayers [ProgressionContext -> Progression
strataLayer, ProgressionContext -> Progression
modeLayer]
layer Layer
TSM = [ProgressionContext -> Progression]
-> ProgressionContext -> Progression
mergeLayers [ProgressionContext -> Progression
triadLayer, ProgressionContext -> Progression
strataLayer, ProgressionContext -> Progression
modeLayer]
layer Layer
PT = ProgressionContext -> Progression
pivotLayer
barAbsPCs :: H.CadenceState -> [Int]
barAbsPCs :: CadenceState -> [Int]
barAbsPCs CadenceState
cs =
let r :: Int
r = PitchClass -> Int
P.unPitchClass (NoteName -> PitchClass
P.pitchClass (CadenceState -> NoteName
H.stateCadenceRoot CadenceState
cs))
in [ (Int
r Int -> Int -> Int
forall a. Num a => a -> a -> a
+ PitchClass -> Int
P.unPitchClass PitchClass
iv) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
12
| PitchClass
iv <- Cadence -> [PitchClass]
H.cadenceIntervals (CadenceState -> Cadence
H.stateCadence CadenceState
cs) ]
barFromPCs :: H.CadenceState -> [Int] -> H.CadenceState
barFromPCs :: CadenceState -> [Int] -> CadenceState
barFromPCs CadenceState
anchor [Int]
pcs =
let rootPC :: Int
rootPC = PitchClass -> Int
P.unPitchClass (NoteName -> PitchClass
P.pitchClass (CadenceState -> NoteName
H.stateCadenceRoot CadenceState
anchor))
ivs :: [Int]
ivs = [ (Int
p Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
rootPC) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
12 | Int
p <- [Int]
pcs ]
built :: CadenceState
built = NoteName -> Movement -> [Int] -> CadenceState
H.mkCadenceStatePCs (CadenceState -> NoteName
H.stateCadenceRoot CadenceState
anchor)
(Cadence -> Movement
H.cadenceMovement (CadenceState -> Cadence
H.stateCadence CadenceState
anchor)) [Int]
ivs
in CadenceState
built { H.stateSpelling = H.stateSpelling anchor }
mergeLayers :: [ProgressionContext -> Progression] -> ProgressionContext -> Progression
mergeLayers :: [ProgressionContext -> Progression]
-> ProgressionContext -> Progression
mergeLayers [ProgressionContext -> Progression]
sels ProgressionContext
pc =
let cols :: [[CadenceState]]
cols = [ Seq CadenceState -> [CadenceState]
forall a. Seq a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (Progression -> Seq CadenceState
Prog.unProgression (ProgressionContext -> Progression
sel ProgressionContext
pc)) | ProgressionContext -> Progression
sel <- [ProgressionContext -> Progression]
sels ]
mergeBar :: [CadenceState] -> CadenceState
mergeBar [CadenceState]
bars = case [CadenceState]
bars of
(CadenceState
anchor : [CadenceState]
_) -> CadenceState -> [Int] -> CadenceState
barFromPCs CadenceState
anchor ((CadenceState -> [Int] -> [Int])
-> [Int] -> [CadenceState] -> [Int]
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ([Int] -> [Int] -> [Int]
forall {t :: * -> *} {a}. (Foldable t, Eq a) => t a -> [a] -> [a]
unionPCs ([Int] -> [Int] -> [Int])
-> (CadenceState -> [Int]) -> CadenceState -> [Int] -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CadenceState -> [Int]
barAbsPCs) [] [CadenceState]
bars)
[] -> String -> CadenceState
forall a. HasCallStack => String -> a
error String
"mergeLayers: empty bar column"
unionPCs :: t a -> [a] -> [a]
unionPCs t a
xs [a]
ys = (a -> [a] -> [a]) -> [a] -> t a -> [a]
forall a b. (a -> b -> b) -> b -> t a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\a
x [a]
acc -> if a
x a -> [a] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [a]
acc then [a]
acc else a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
acc) [a]
ys t a
xs
in [CadenceState] -> Progression
Prog.fromCadenceStates (([CadenceState] -> CadenceState)
-> [[CadenceState]] -> [CadenceState]
forall a b. (a -> b) -> [a] -> [b]
map [CadenceState] -> CadenceState
mergeBar ([[CadenceState]] -> [[CadenceState]]
forall a. [[a]] -> [[a]]
transpose [[CadenceState]]
cols))
pivotLayer :: ProgressionContext -> Progression
pivotLayer :: ProgressionContext -> Progression
pivotLayer ProgressionContext
pc =
let ts :: Seq CadenceState
ts = Progression -> Seq CadenceState
Prog.unProgression (ProgressionContext -> Progression
triadLayer ProgressionContext
pc)
ss :: Seq CadenceState
ss = Progression -> Seq CadenceState
Prog.unProgression (ProgressionContext -> Progression
strataLayer ProgressionContext
pc)
ms :: Seq CadenceState
ms = Progression -> Seq CadenceState
Prog.unProgression (ProgressionContext -> Progression
modeLayer ProgressionContext
pc)
pivotBar :: CadenceState -> CadenceState -> CadenceState -> CadenceState
pivotBar CadenceState
tBar CadenceState
sBar CadenceState
mBar =
let common :: [Int]
common = [ Int
p | Int
p <- CadenceState -> [Int]
barAbsPCs CadenceState
tBar
, Int
p Int -> [Int] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` CadenceState -> [Int]
barAbsPCs CadenceState
sBar, Int
p Int -> [Int] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` CadenceState -> [Int]
barAbsPCs CadenceState
mBar ]
in if [Int] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
common Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== [Int] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (CadenceState -> [Int]
barAbsPCs CadenceState
tBar)
then CadenceState
tBar
else CadenceState -> [Int] -> CadenceState
barFromPCs (CadenceState -> [Int] -> CadenceState
anchorOn CadenceState
tBar [Int]
common) [Int]
common
anchorOn :: CadenceState -> [Int] -> CadenceState
anchorOn CadenceState
tBar [Int]
common =
let root :: Int
root = case [Int]
common of
[Int
a, Int
b] -> if (Int
b Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
a) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
12 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
6 then Int
a else Int
b
[Int
a] -> Int
a
[Int]
_ -> PitchClass -> Int
P.unPitchClass (NoteName -> PitchClass
P.pitchClass (CadenceState -> NoteName
H.stateCadenceRoot CadenceState
tBar))
in CadenceState
tBar { H.stateCadenceRoot =
H.enharmonicFunc (H.stateSpelling tBar) (P.mkPitchClass root) }
in Seq CadenceState -> Progression
Progression ((CadenceState -> CadenceState -> CadenceState -> CadenceState)
-> Seq CadenceState
-> Seq CadenceState
-> Seq CadenceState
-> Seq CadenceState
forall a b c d.
(a -> b -> c -> d) -> Seq a -> Seq b -> Seq c -> Seq d
Seq.zipWith3 CadenceState -> CadenceState -> CadenceState -> CadenceState
pivotBar Seq CadenceState
ts Seq CadenceState
ss Seq CadenceState
ms)
pcLength :: ProgressionContext -> Int
pcLength :: ProgressionContext -> Int
pcLength = Progression -> Int
progLength (Progression -> Int)
-> (ProgressionContext -> Progression) -> ProgressionContext -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProgressionContext -> Progression
triadLayer
fromProgression :: Progression -> ProgressionContext
fromProgression :: Progression -> ProgressionContext
fromProgression Progression
p = ProgressionContext
{ triadLayer :: Progression
triadLayer = Progression
p
, strataLayer :: Progression
strataLayer = Progression
p
, modeLayer :: Progression
modeLayer = Progression
p
, pcProvenance :: Maybe (Seq (Tristrata, StrataLabel))
pcProvenance = Maybe (Seq (Tristrata, StrataLabel))
forall a. Maybe a
Nothing
, pcFamily :: Family
pcFamily = Progression -> Family
inferFamilyFromProgression Progression
p
}
inferFamilyFromProgression :: Progression -> Family
inferFamilyFromProgression :: Progression -> Family
inferFamilyFromProgression Progression
p =
let sizes :: [Int]
sizes = [ [PitchClass] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (Cadence -> [PitchClass]
H.cadenceIntervals (CadenceState -> Cadence
H.stateCadence CadenceState
cs))
| CadenceState
cs <- Seq CadenceState -> [CadenceState]
forall a. Seq a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (Progression -> Seq CadenceState
Prog.unProgression Progression
p) ]
in if Bool -> Bool
not ([Int] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Int]
sizes) Bool -> Bool -> Bool
&& (Int -> Bool) -> [Int] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
4) [Int]
sizes then Family
FExtended else Family
FTriad
liftPC :: (Progression -> Progression) -> ProgressionContext -> ProgressionContext
liftPC :: (Progression -> Progression)
-> ProgressionContext -> ProgressionContext
liftPC Progression -> Progression
f ProgressionContext
pc = ProgressionContext -> ProgressionContext
normalizeFamily ProgressionContext
{ triadLayer :: Progression
triadLayer = Progression -> Progression
f (ProgressionContext -> Progression
triadLayer ProgressionContext
pc)
, strataLayer :: Progression
strataLayer = Progression -> Progression
f (ProgressionContext -> Progression
strataLayer ProgressionContext
pc)
, modeLayer :: Progression
modeLayer = Progression -> Progression
f (ProgressionContext -> Progression
modeLayer ProgressionContext
pc)
, pcProvenance :: Maybe (Seq (Tristrata, StrataLabel))
pcProvenance = Maybe (Seq (Tristrata, StrataLabel))
forall a. Maybe a
Nothing
, pcFamily :: Family
pcFamily = ProgressionContext -> Family
pcFamily ProgressionContext
pc
}
liftPCAligned :: (forall a. Seq a -> Seq a) -> ProgressionContext -> ProgressionContext
liftPCAligned :: (forall a. Seq a -> Seq a)
-> ProgressionContext -> ProgressionContext
liftPCAligned forall a. Seq a -> Seq a
f ProgressionContext
pc = ProgressionContext
{ triadLayer :: Progression
triadLayer = Progression -> Progression
onProg (ProgressionContext -> Progression
triadLayer ProgressionContext
pc)
, strataLayer :: Progression
strataLayer = Progression -> Progression
onProg (ProgressionContext -> Progression
strataLayer ProgressionContext
pc)
, modeLayer :: Progression
modeLayer = Progression -> Progression
onProg (ProgressionContext -> Progression
modeLayer ProgressionContext
pc)
, pcProvenance :: Maybe (Seq (Tristrata, StrataLabel))
pcProvenance = (Seq (Tristrata, StrataLabel) -> Seq (Tristrata, StrataLabel))
-> Maybe (Seq (Tristrata, StrataLabel))
-> Maybe (Seq (Tristrata, StrataLabel))
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Seq (Tristrata, StrataLabel) -> Seq (Tristrata, StrataLabel)
forall a. Seq a -> Seq a
f (ProgressionContext -> Maybe (Seq (Tristrata, StrataLabel))
pcProvenance ProgressionContext
pc)
, pcFamily :: Family
pcFamily = ProgressionContext -> Family
pcFamily ProgressionContext
pc
}
where onProg :: Progression -> Progression
onProg = Seq CadenceState -> Progression
Progression (Seq CadenceState -> Progression)
-> (Progression -> Seq CadenceState) -> Progression -> Progression
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Seq CadenceState -> Seq CadenceState
forall a. Seq a -> Seq a
f (Seq CadenceState -> Seq CadenceState)
-> (Progression -> Seq CadenceState)
-> Progression
-> Seq CadenceState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Progression -> Seq CadenceState
Prog.unProgression
liftPCSubst :: (Progression -> Progression) -> ProgressionContext -> ProgressionContext
liftPCSubst :: (Progression -> Progression)
-> ProgressionContext -> ProgressionContext
liftPCSubst Progression -> Progression
f ProgressionContext
pc =
let out :: ProgressionContext
out = (Progression -> Progression)
-> ProgressionContext -> ProgressionContext
liftPC Progression -> Progression
f ProgressionContext
pc
in ProgressionContext
out { pcFamily = case pcFamily out of
Family
FPoly -> Family
FTriad
Family
fam -> Family
fam }
normalizeFamily :: ProgressionContext -> ProgressionContext
normalizeFamily :: ProgressionContext -> ProgressionContext
normalizeFamily ProgressionContext
pc
| ProgressionContext -> Family
pcFamily ProgressionContext
pc Family -> Family -> Bool
forall a. Eq a => a -> a -> Bool
== Family
FStrata, Maybe (Seq (Tristrata, StrataLabel))
Nothing <- ProgressionContext -> Maybe (Seq (Tristrata, StrataLabel))
pcProvenance ProgressionContext
pc = ProgressionContext
pc { pcFamily = FTriad }
| Bool
otherwise = ProgressionContext
pc
instance Semigroup ProgressionContext where
ProgressionContext
a <> :: ProgressionContext -> ProgressionContext -> ProgressionContext
<> ProgressionContext
b
| ProgressionContext
a ProgressionContext -> ProgressionContext -> Bool
forall a. Eq a => a -> a -> Bool
== ProgressionContext
forall a. Monoid a => a
mempty = ProgressionContext
b
| ProgressionContext
b ProgressionContext -> ProgressionContext -> Bool
forall a. Eq a => a -> a -> Bool
== ProgressionContext
forall a. Monoid a => a
mempty = ProgressionContext
a
| Bool
otherwise = ProgressionContext -> ProgressionContext
normalizeFamily ProgressionContext
{ triadLayer :: Progression
triadLayer = ProgressionContext -> Progression
triadLayer ProgressionContext
a Progression -> Progression -> Progression
forall a. Semigroup a => a -> a -> a
<> ProgressionContext -> Progression
triadLayer ProgressionContext
b
, strataLayer :: Progression
strataLayer = ProgressionContext -> Progression
strataLayer ProgressionContext
a Progression -> Progression -> Progression
forall a. Semigroup a => a -> a -> a
<> ProgressionContext -> Progression
strataLayer ProgressionContext
b
, modeLayer :: Progression
modeLayer = ProgressionContext -> Progression
modeLayer ProgressionContext
a Progression -> Progression -> Progression
forall a. Semigroup a => a -> a -> a
<> ProgressionContext -> Progression
modeLayer ProgressionContext
b
, pcProvenance :: Maybe (Seq (Tristrata, StrataLabel))
pcProvenance = case (ProgressionContext -> Maybe (Seq (Tristrata, StrataLabel))
pcProvenance ProgressionContext
a, ProgressionContext -> Maybe (Seq (Tristrata, StrataLabel))
pcProvenance ProgressionContext
b) of
(Just Seq (Tristrata, StrataLabel)
sa, Just Seq (Tristrata, StrataLabel)
sb) -> Seq (Tristrata, StrataLabel)
-> Maybe (Seq (Tristrata, StrataLabel))
forall a. a -> Maybe a
Just (Seq (Tristrata, StrataLabel)
sa Seq (Tristrata, StrataLabel)
-> Seq (Tristrata, StrataLabel) -> Seq (Tristrata, StrataLabel)
forall a. Seq a -> Seq a -> Seq a
Seq.>< Seq (Tristrata, StrataLabel)
sb)
(Maybe (Seq (Tristrata, StrataLabel)),
Maybe (Seq (Tristrata, StrataLabel)))
_ -> Maybe (Seq (Tristrata, StrataLabel))
forall a. Maybe a
Nothing
, pcFamily :: Family
pcFamily = if ProgressionContext -> Family
pcFamily ProgressionContext
a Family -> Family -> Bool
forall a. Eq a => a -> a -> Bool
== ProgressionContext -> Family
pcFamily ProgressionContext
b then ProgressionContext -> Family
pcFamily ProgressionContext
a else Family
FTriad
}
instance Monoid ProgressionContext where
mempty :: ProgressionContext
mempty = Progression
-> Progression
-> Progression
-> Maybe (Seq (Tristrata, StrataLabel))
-> Family
-> ProgressionContext
ProgressionContext Progression
forall a. Monoid a => a
mempty Progression
forall a. Monoid a => a
mempty Progression
forall a. Monoid a => a
mempty Maybe (Seq (Tristrata, StrataLabel))
forall a. Maybe a
Nothing Family
FTriad
pcSplice :: ProgressionContext -> Int -> Int -> ProgressionContext -> ProgressionContext
pcSplice :: ProgressionContext
-> Int -> Int -> ProgressionContext -> ProgressionContext
pcSplice ProgressionContext
src Int
start Int
end ProgressionContext
ins =
let triad' :: Progression
triad' = Progression -> Int -> Int -> [CadenceState] -> Progression
Prog.spliceProgression
(ProgressionContext -> Progression
triadLayer ProgressionContext
src) Int
start Int
end
(Seq CadenceState -> [CadenceState]
forall a. Seq a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (Progression -> Seq CadenceState
Prog.unProgression (ProgressionContext -> Progression
triadLayer ProgressionContext
ins)))
strata' :: Progression
strata' = Seq CadenceState -> Progression
Progression
(Seq CadenceState
-> Int -> Int -> Seq CadenceState -> Seq CadenceState
forall a. Seq a -> Int -> Int -> Seq a -> Seq a
spliceSeq (Progression -> Seq CadenceState
Prog.unProgression (ProgressionContext -> Progression
strataLayer ProgressionContext
src))
Int
start Int
end
(Progression -> Seq CadenceState
Prog.unProgression (ProgressionContext -> Progression
strataLayer ProgressionContext
ins)))
mode' :: Progression
mode' = Seq CadenceState -> Progression
Progression
(Seq CadenceState
-> Int -> Int -> Seq CadenceState -> Seq CadenceState
forall a. Seq a -> Int -> Int -> Seq a -> Seq a
spliceSeq (Progression -> Seq CadenceState
Prog.unProgression (ProgressionContext -> Progression
modeLayer ProgressionContext
src))
Int
start Int
end
(Progression -> Seq CadenceState
Prog.unProgression (ProgressionContext -> Progression
modeLayer ProgressionContext
ins)))
prov' :: Maybe (Seq (Tristrata, StrataLabel))
prov' = case (ProgressionContext -> Maybe (Seq (Tristrata, StrataLabel))
pcProvenance ProgressionContext
src, ProgressionContext -> Maybe (Seq (Tristrata, StrataLabel))
pcProvenance ProgressionContext
ins) of
(Just Seq (Tristrata, StrataLabel)
s, Just Seq (Tristrata, StrataLabel)
i) -> Seq (Tristrata, StrataLabel)
-> Maybe (Seq (Tristrata, StrataLabel))
forall a. a -> Maybe a
Just (Seq (Tristrata, StrataLabel)
-> Int
-> Int
-> Seq (Tristrata, StrataLabel)
-> Seq (Tristrata, StrataLabel)
forall a. Seq a -> Int -> Int -> Seq a -> Seq a
spliceSeq Seq (Tristrata, StrataLabel)
s Int
start Int
end Seq (Tristrata, StrataLabel)
i)
(Maybe (Seq (Tristrata, StrataLabel)),
Maybe (Seq (Tristrata, StrataLabel)))
_ -> Maybe (Seq (Tristrata, StrataLabel))
forall a. Maybe a
Nothing
in Progression
-> Progression
-> Progression
-> Maybe (Seq (Tristrata, StrataLabel))
-> Family
-> ProgressionContext
ProgressionContext Progression
triad' Progression
strata' Progression
mode' Maybe (Seq (Tristrata, StrataLabel))
prov' (ProgressionContext -> Family
pcFamily ProgressionContext
src)
spliceSeq :: Seq a -> Int -> Int -> Seq a -> Seq a
spliceSeq :: forall a. Seq a -> Int -> Int -> Seq a -> Seq a
spliceSeq Seq a
sq Int
start Int
end Seq a
ins =
let n :: Int
n = Seq a -> Int
forall a. Seq a -> Int
Seq.length Seq a
sq
in if Int
start Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
end then
let prefix :: Seq a
prefix = Int -> Seq a -> Seq a
forall a. Int -> Seq a -> Seq a
Seq.take (Int
start Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Seq a
sq
suffix :: Seq a
suffix = Int -> Seq a -> Seq a
forall a. Int -> Seq a -> Seq a
Seq.drop Int
end Seq a
sq
in Seq a
prefix Seq a -> Seq a -> Seq a
forall a. Seq a -> Seq a -> Seq a
>< Seq a
ins Seq a -> Seq a -> Seq a
forall a. Seq a -> Seq a -> Seq a
>< Seq a
suffix
else
let kept :: Seq a
kept = Int -> Seq a -> Seq a
forall a. Int -> Seq a -> Seq a
Seq.take (Int
start Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
end Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) (Int -> Seq a -> Seq a
forall a. Int -> Seq a -> Seq a
Seq.drop Int
end Seq a
sq)
headCount :: Int
headCount = Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
start Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
newAtEnd :: Seq a
newAtEnd = Int -> Seq a -> Seq a
forall a. Int -> Seq a -> Seq a
Seq.take Int
headCount Seq a
ins
newAtStart :: Seq a
newAtStart = Int -> Seq a -> Seq a
forall a. Int -> Seq a -> Seq a
Seq.drop Int
headCount Seq a
ins
in Seq a
newAtStart Seq a -> Seq a -> Seq a
forall a. Seq a -> Seq a -> Seq a
>< Seq a
kept Seq a -> Seq a -> Seq a
forall a. Seq a -> Seq a -> Seq a
>< Seq a
newAtEnd