-- Copyright 2021 Evan Laforge
-- This program is distributed under the terms of the GNU General Public
-- License 3.0, see COPYING or http://www.gnu.org/licenses/gpl-3.0.txt

module Solkattu.Score.Mohra where
import           Prelude hiding ((.), (^), repeat)

import qualified Solkattu.Korvai as Korvai

import           Solkattu.Dsl.Generic


korvai :: ([Korvai.Section (SequenceT sollu)] -> Korvai)
    -> (a -> SequenceT sollu) -> (a, a, a) -> (a, a, a) -> Korvai
korvai :: forall sollu a.
([Section (SequenceT sollu)] -> Korvai)
-> (a -> SequenceT sollu) -> (a, a, a) -> (a, a, a) -> Korvai
korvai [Section (SequenceT sollu)] -> Korvai
makeKorvai a -> SequenceT sollu
transform (a, a, a)
as (a, a, a)
bs = forall sollu a.
([Section (SequenceT sollu)] -> Korvai)
-> (a -> SequenceT sollu) -> [((a, a, a), (a, a, a))] -> Korvai
korvais [Section (SequenceT sollu)] -> Korvai
makeKorvai a -> SequenceT sollu
transform [((a, a, a)
as, (a, a, a)
bs)]

korvais :: ([Korvai.Section (SequenceT sollu)] -> Korvai)
    -> (a -> SequenceT sollu) -> [((a, a, a), (a, a, a))] -> Korvai
korvais :: forall sollu a.
([Section (SequenceT sollu)] -> Korvai)
-> (a -> SequenceT sollu) -> [((a, a, a), (a, a, a))] -> Korvai
korvais [Section (SequenceT sollu)] -> Korvai
makeKorvai a -> SequenceT sollu
transform =
    Korvai -> Korvai
mohra forall b c a. (b -> c) -> (a -> b) -> a -> c
 [Section (SequenceT sollu)] -> Korvai
makeKorvai forall b c a. (b -> c) -> (a -> b) -> a -> c
 forall a b. (a -> b) -> [a] -> [b]
map (forall a. a -> Section a
section forall b c a. (b -> c) -> (a -> b) -> a -> c
 forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (forall a sollu.
(a -> SequenceT sollu) -> (a, a, a) -> (a, a, a) -> SequenceT sollu
make a -> SequenceT sollu
transform))

-- | Make a mohra in the standard structure.
make :: (a -> SequenceT sollu) -> (a, a, a) -> (a, a, a) -> SequenceT sollu
make :: forall a sollu.
(a -> SequenceT sollu) -> (a, a, a) -> (a, a, a) -> SequenceT sollu
make a -> SequenceT sollu
transform (a
a1_, a
a2_, a
a3_) (a
b1_, a
b2_, a
b3_) =
      SequenceT sollu
a123forall a. Monoid a => a -> a -> a
.SequenceT sollu
b1 forall a. Monoid a => a -> a -> a
. SequenceT sollu
a123forall a. Monoid a => a -> a -> a
.SequenceT sollu
b1
    forall a. Monoid a => a -> a -> a
. SequenceT sollu
a123forall a. Monoid a => a -> a -> a
.SequenceT sollu
b2
    forall a. Monoid a => a -> a -> a
. SequenceT sollu
a1forall a. Monoid a => a -> a -> a
.SequenceT sollu
b2 forall a. Monoid a => a -> a -> a
. SequenceT sollu
a3forall a. Monoid a => a -> a -> a
.SequenceT sollu
b3
    where
    a123 :: SequenceT sollu
a123 = SequenceT sollu
a1forall a. Monoid a => a -> a -> a
.SequenceT sollu
a2forall a. Monoid a => a -> a -> a
.SequenceT sollu
a3
    (SequenceT sollu
a1, SequenceT sollu
a2, SequenceT sollu
a3) = (a -> SequenceT sollu
t a
a1_, a -> SequenceT sollu
t a
a2_, a -> SequenceT sollu
t a
a3_)
    (SequenceT sollu
b1, SequenceT sollu
b2, SequenceT sollu
b3) = (a -> SequenceT sollu
t a
b1_, a -> SequenceT sollu
t a
b2_, a -> SequenceT sollu
t a
b3_)
    t :: a -> SequenceT sollu
t = forall sollu. SequenceT sollu -> SequenceT sollu
group forall b c a. (b -> c) -> (a -> b) -> a -> c
 a -> SequenceT sollu
transform

-- | Make a 2 speed mohra.
make2 :: (a -> SequenceT sollu) -> ((a, a, a), (a, a, a)) -> SequenceT sollu
make2 :: forall a sollu.
(a -> SequenceT sollu) -> ((a, a, a), (a, a, a)) -> SequenceT sollu
make2 a -> SequenceT sollu
transform ((a
a1_, a
a2_, a
a3_), (a
b1_, a
b2_, a
b3_)) =
    SequenceT sollu
a123forall a. Monoid a => a -> a -> a
.SequenceT sollu
b1 forall a. Monoid a => a -> a -> a
. forall g sollu. Sequence g sollu -> Sequence g sollu
su (SequenceT sollu
a123forall a. Monoid a => a -> a -> a
.SequenceT sollu
b1) forall a. Monoid a => a -> a -> a
. SequenceT sollu
a123forall a. Monoid a => a -> a -> a
.SequenceT sollu
b1 forall a. Monoid a => a -> a -> a
. forall g sollu. Sequence g sollu -> Sequence g sollu
su (SequenceT sollu
a123forall a. Monoid a => a -> a -> a
.SequenceT sollu
b1)
    forall a. Monoid a => a -> a -> a
. SequenceT sollu
a123forall a. Monoid a => a -> a -> a
.SequenceT sollu
b2 forall a. Monoid a => a -> a -> a
. forall g sollu. Sequence g sollu -> Sequence g sollu
su (SequenceT sollu
a123forall a. Monoid a => a -> a -> a
.SequenceT sollu
b2)
    forall a. Monoid a => a -> a -> a
. SequenceT sollu
a1forall a. Monoid a => a -> a -> a
.SequenceT sollu
b2 forall a. Monoid a => a -> a -> a
. forall g sollu. Sequence g sollu -> Sequence g sollu
su (SequenceT sollu
a1forall a. Monoid a => a -> a -> a
.SequenceT sollu
b2)
    forall a. Monoid a => a -> a -> a
. SequenceT sollu
a3forall a. Monoid a => a -> a -> a
.SequenceT sollu
b3 forall a. Monoid a => a -> a -> a
. forall g sollu. Sequence g sollu -> Sequence g sollu
su (SequenceT sollu
a3forall a. Monoid a => a -> a -> a
.SequenceT sollu
b3)
    where
    (SequenceT sollu
a1, SequenceT sollu
a2, SequenceT sollu
a3) = (a -> SequenceT sollu
t a
a1_, a -> SequenceT sollu
t a
a2_, a -> SequenceT sollu
t a
a3_)
    (SequenceT sollu
b1, SequenceT sollu
b2, SequenceT sollu
b3) = (a -> SequenceT sollu
t a
b1_, a -> SequenceT sollu
t a
b2_, a -> SequenceT sollu
t a
b3_)
    a123 :: SequenceT sollu
a123 = SequenceT sollu
a1forall a. Monoid a => a -> a -> a
.SequenceT sollu
a2forall a. Monoid a => a -> a -> a
.SequenceT sollu
a3
    t :: a -> SequenceT sollu
t = forall sollu. SequenceT sollu -> SequenceT sollu
group forall b c a. (b -> c) -> (a -> b) -> a -> c
 a -> SequenceT sollu
transform