-- | Functions to generate a click track from a metric structure.
module Music.Theory.Duration.ClickTrack where

import Data.Bifunctor {- base -}
import Data.Function {- base -}
import Data.List {- base -}
import Data.Maybe {- base -}

import qualified Music.Theory.List as List {- hmt-base -}

import qualified Music.Theory.Duration.Rq as T {- hmt -}
import qualified Music.Theory.Time_Signature as T {- hmt -}
import qualified Music.Theory.Time.Seq as T {- hmt -}

-- | 1-indexed.
type Measure = Int

-- | 1-indexed.
type Pulse = Int

-- | Measures given as 'T.Rq' divisions, Mdv abbreviates measure divisions.
type Mdv = [[T.Rq]]

{- | Absolute 'T.Rq' locations grouped in measures.
     mrq abbreviates measure rational quarter-notes.
     Locations are zero-indexed.
-}
type Mrq = [[T.Rq]]

{- | Transform Mdv to Mrq.

> mdv_to_mrq [[1,2,1],[3,2,1]] == [[0,1,3],[4,7,9]]
-}
mdv_to_mrq :: Mdv -> Mrq
mdv_to_mrq :: Mdv -> Mdv
mdv_to_mrq = forall a b. (a, b) -> b
snd forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) s a b.
Traversable t =>
(s -> a -> (s, b)) -> s -> t a -> (s, t b)
mapAccumL forall t. Num t => t -> [t] -> (t, [t])
List.dx_d' Rq
0

{- | Lookup function for ('Measure','Pulse') indexed structure.
     mp abbreviates Measure Pulse.
-}
mp_lookup_err :: [[t]] -> (Measure,Pulse) -> t
mp_lookup_err :: forall t. [[t]] -> (Measure, Measure) -> t
mp_lookup_err [[t]]
sq (Measure
m,Measure
p) =
    if Measure
m forall a. Ord a => a -> a -> Bool
< Measure
1 Bool -> Bool -> Bool
|| Measure
p forall a. Ord a => a -> a -> Bool
< Measure
1
    then forall a. HasCallStack => String -> a
error (forall a. Show a => a -> String
show (String
"mp_lookup_err: one indexed?",Measure
m,Measure
p))
    else ([[t]]
sq forall a. [a] -> Measure -> a
!! (Measure
m forall a. Num a => a -> a -> a
- Measure
1)) forall a. [a] -> Measure -> a
!! (Measure
p forall a. Num a => a -> a -> a
- Measure
1)

-- | Comparison for ('Measure','Pulse') indices.
mp_compare :: (Measure,Pulse) -> (Measure,Pulse) -> Ordering
mp_compare :: (Measure, Measure) -> (Measure, Measure) -> Ordering
mp_compare = forall a. Compare_F a -> Compare_F a -> Compare_F a
List.two_stage_compare (forall a. Ord a => a -> a -> Ordering
compare forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` forall a b. (a, b) -> a
fst) (forall a. Ord a => a -> a -> Ordering
compare forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` forall a b. (a, b) -> b
snd)

-- * Ct

{- | Latch measures (ie. make measures contiguous, hold previous value).
     Arguments are the number of measures and the default (intial) value.

> unzip (ct_ext 10 'a' [(3,'b'),(8,'c')]) == ([1..10],"aabbbbbccc")
-}
ct_ext :: Int -> t -> T.Tseq Measure t -> T.Tseq Measure t
ct_ext :: forall t. Measure -> t -> Tseq Measure t -> Tseq Measure t
ct_ext Measure
n t
def Tseq Measure t
sq = forall t a. Ord t => a -> Tseq t a -> [t] -> Tseq t a
T.tseq_latch t
def Tseq Measure t
sq [Measure
1 .. Measure
n]

-- | Variant that requires a value at measure one (first measure).
ct_ext1 :: Int -> T.Tseq Measure t -> T.Tseq Measure t
ct_ext1 :: forall t. Measure -> Tseq Measure t -> Tseq Measure t
ct_ext1 Measure
n Tseq Measure t
sq =
    case Tseq Measure t
sq of
      (Measure
1,t
e) : Tseq Measure t
sq' -> forall t. Measure -> t -> Tseq Measure t -> Tseq Measure t
ct_ext Measure
n t
e Tseq Measure t
sq'
      Tseq Measure t
_ -> forall a. HasCallStack => String -> a
error String
"ct_ext1"

-- | 'T.rts_divisions' of 'ct_ext1'.
ct_dv_seq :: Int -> T.Tseq Measure T.Rational_Time_Signature -> [(Measure,[[T.Rq]])]
ct_dv_seq :: Measure -> Tseq Measure Rational_Time_Signature -> [(Measure, Mdv)]
ct_dv_seq Measure
n Tseq Measure Rational_Time_Signature
ts = forall a b. (a -> b) -> [a] -> [b]
map (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Rational_Time_Signature -> Mdv
T.rts_divisions) (forall t. Measure -> Tseq Measure t -> Tseq Measure t
ct_ext1 Measure
n Tseq Measure Rational_Time_Signature
ts)

-- | 'ct_dv_seq' without measures numbers (which are 1..n)
ct_mdv_seq :: Int -> T.Tseq Measure T.Rational_Time_Signature -> [[T.Rq]]
ct_mdv_seq :: Measure -> Tseq Measure Rational_Time_Signature -> Mdv
ct_mdv_seq Measure
n = forall a b. (a -> b) -> [a] -> [b]
map (forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Measure -> Tseq Measure Rational_Time_Signature -> [(Measure, Mdv)]
ct_dv_seq Measure
n

-- | 'mdv_to_mrq' of 'ct_mdv_seq'.
ct_rq :: Int -> T.Tseq Measure T.Rational_Time_Signature -> [[T.Rq]]
ct_rq :: Measure -> Tseq Measure Rational_Time_Signature -> Mdv
ct_rq Measure
n Tseq Measure Rational_Time_Signature
ts = Mdv -> Mdv
mdv_to_mrq (Measure -> Tseq Measure Rational_Time_Signature -> Mdv
ct_mdv_seq Measure
n Tseq Measure Rational_Time_Signature
ts)

ct_mp_lookup :: [[T.Rq]] -> (Measure,Pulse) -> T.Rq
ct_mp_lookup :: Mdv -> (Measure, Measure) -> Rq
ct_mp_lookup = forall t. [[t]] -> (Measure, Measure) -> t
mp_lookup_err forall b c a. (b -> c) -> (a -> b) -> a -> c
. Mdv -> Mdv
mdv_to_mrq

ct_m_to_rq :: [[T.Rq]] -> [(Measure,t)] -> [(T.Rq,t)]
ct_m_to_rq :: forall t. Mdv -> [(Measure, t)] -> [(Rq, t)]
ct_m_to_rq Mdv
sq = forall a b. (a -> b) -> [a] -> [b]
map (\(Measure
m,t
c) -> (Mdv -> (Measure, Measure) -> Rq
ct_mp_lookup Mdv
sq (Measure
m,Measure
1),t
c))

-- | Latch rehearsal mark sequence, only indicating marks.  Initial mark is @.@.
--
-- > ct_mark_seq 2 [] == [(1,Just '.'),(2,Nothing)]
--
-- > let r = [(1,Just '.'),(3,Just 'A'),(8,Just 'B')]
-- > in filter (isJust . snd) (ct_mark_seq 10 [(3,'A'),(8,'B')]) == r
ct_mark_seq :: Int -> T.Tseq Measure Char -> T.Tseq Measure (Maybe Char)
ct_mark_seq :: Measure -> Tseq Measure Char -> Tseq Measure (Maybe Char)
ct_mark_seq Measure
n Tseq Measure Char
mk = forall a t. Eq a => [(t, a)] -> [(t, Maybe a)]
T.seq_changed (forall t. Measure -> t -> Tseq Measure t -> Tseq Measure t
ct_ext Measure
n Char
'.' Tseq Measure Char
mk)

-- | Indicate measures prior to marks.
--
-- > ct_pre_mark [] == []
-- > ct_pre_mark [(1,'A')] == []
-- > ct_pre_mark [(3,'A'),(8,'B')] == [(2,Just ()),(7,Just ())]
ct_pre_mark :: [(Measure,a)] -> [(Measure,Maybe ())]
ct_pre_mark :: forall a. [(Measure, a)] -> [(Measure, Maybe ())]
ct_pre_mark = forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (\(Measure
m,a
_) -> if Measure
m forall a. Ord a => a -> a -> Bool
<= Measure
1 then forall a. Maybe a
Nothing else forall a. a -> Maybe a
Just (Measure
m forall a. Num a => a -> a -> a
- Measure
1,forall a. a -> Maybe a
Just ()))

-- | Contiguous pre-mark sequence.
--
-- > ct_pre_mark_seq 1 [(1,'A')] == [(1,Nothing)]
-- > ct_pre_mark_seq 10 [(3,'A'),(8,'B')]
ct_pre_mark_seq :: Measure -> T.Tseq Measure Char -> T.Tseq Measure (Maybe ())
ct_pre_mark_seq :: Measure -> Tseq Measure Char -> [(Measure, Maybe ())]
ct_pre_mark_seq Measure
n Tseq Measure Char
mk =
    let pre :: [(Measure, Maybe ())]
pre = forall a. [(Measure, a)] -> [(Measure, Maybe ())]
ct_pre_mark Tseq Measure Char
mk
    in forall t a.
Ord t =>
(a -> a -> a) -> Tseq t a -> Tseq t a -> Tseq t a
T.tseq_merge_resolve forall a b. a -> b -> a
const [(Measure, Maybe ())]
pre (forall a b. [a] -> [b] -> [(a, b)]
zip [Measure
1 .. Measure
n] (forall a. a -> [a]
repeat forall a. Maybe a
Nothing))

ct_tempo_lseq_rq :: [[T.Rq]] -> T.Lseq (Measure,Pulse) T.Rq -> T.Lseq T.Rq T.Rq
ct_tempo_lseq_rq :: Mdv -> Lseq (Measure, Measure) Rq -> Lseq Rq Rq
ct_tempo_lseq_rq Mdv
sq = forall t t' a. (t -> t') -> Lseq t a -> Lseq t' a
T.lseq_tmap (Mdv -> (Measure, Measure) -> Rq
ct_mp_lookup Mdv
sq)

-- | Interpolating lookup of tempo sequence ('T.lseq_lookup_err').
ct_tempo_at :: T.Lseq T.Rq T.Rq -> T.Rq -> Rational
ct_tempo_at :: Lseq Rq Rq -> Rq -> Rq
ct_tempo_at = forall t e.
(Fractional t, Real t, Fractional e) =>
(t -> t -> Ordering) -> Lseq t e -> t -> e
T.lseq_lookup_err forall a. Ord a => a -> a -> Ordering
compare

-- | Types of nodes.
data Ct_Node = Ct_Mark T.Rq -- ^ The start of a measure with a rehearsal mark.
             | Ct_Start T.Rq -- ^ The start of a regular measure.
             | Ct_Normal T.Rq -- ^ A regular pulse.
             | Ct_Edge T.Rq -- ^ The start of a pulse group within a measure.
             | Ct_Pre T.Rq -- ^ A regular pulse in a measure prior to a rehearsal mark.
             | Ct_End -- ^ The end of the track.
               deriving (Ct_Node -> Ct_Node -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Ct_Node -> Ct_Node -> Bool
$c/= :: Ct_Node -> Ct_Node -> Bool
== :: Ct_Node -> Ct_Node -> Bool
$c== :: Ct_Node -> Ct_Node -> Bool
Eq,Measure -> Ct_Node -> ShowS
[Ct_Node] -> ShowS
Ct_Node -> String
forall a.
(Measure -> a -> ShowS)
-> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Ct_Node] -> ShowS
$cshowList :: [Ct_Node] -> ShowS
show :: Ct_Node -> String
$cshow :: Ct_Node -> String
showsPrec :: Measure -> Ct_Node -> ShowS
$cshowsPrec :: Measure -> Ct_Node -> ShowS
Show)

-- | Lead-in of @(pulse,tempo,count)@.
ct_leadin :: (T.Rq,Double,Int) -> T.Dseq Double Ct_Node
ct_leadin :: (Rq, Double, Measure) -> Dseq Double Ct_Node
ct_leadin (Rq
du,Double
tm,Measure
n) = forall a. Measure -> a -> [a]
replicate Measure
n (forall a b. (Real a, Fractional b) => a -> b
realToFrac Rq
du forall a. Num a => a -> a -> a
* (Double
60 forall a. Fractional a => a -> a -> a
/ Double
tm),Rq -> Ct_Node
Ct_Normal Rq
du)

-- | Prepend initial element to start of list.
--
-- > delay1 "abc" == "aabc"
delay1 :: [a] -> [a]
delay1 :: forall a. [a] -> [a]
delay1 [a]
l =
    case [a]
l of
      [] -> forall a. HasCallStack => String -> a
error String
"delay1: []"
      a
e:[a]
_ -> a
e forall a. a -> [a] -> [a]
: [a]
l

{- | Generate Ct measure.
     Calculates durations of events considering only the tempo at the start of the event.
     To be correct it should consider the tempo envelope through the event.
-}
ct_measure:: T.Lseq T.Rq T.Rq -> ([T.Rq],Maybe Char,Maybe (),[[T.Rq]]) -> [(Rational,Ct_Node)]
ct_measure :: Lseq Rq Rq -> ([Rq], Maybe Char, Maybe (), Mdv) -> [(Rq, Ct_Node)]
ct_measure Lseq Rq Rq
sq ([Rq]
mrq,Maybe Char
mk,Maybe ()
pr,Mdv
dv) =
    let dv' :: [(Measure, Rq)]
dv' = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (forall a b. [a] -> [b] -> [(a, b)]
zip [Measure
1::Int ..]) Mdv
dv
        f :: (a, Rq, (a, Rq)) -> (Rq, Ct_Node)
f (a
p,Rq
rq,(a
g,Rq
du)) =
            let nm :: Ct_Node
nm = if a
p forall a. Eq a => a -> a -> Bool
== a
1
                     then case Maybe Char
mk of
                            Maybe Char
Nothing -> Rq -> Ct_Node
Ct_Start Rq
du
                            Just Char
_ -> Rq -> Ct_Node
Ct_Mark Rq
du
                     else if Maybe ()
pr forall a. Eq a => a -> a -> Bool
== forall a. a -> Maybe a
Just ()
                          then Rq -> Ct_Node
Ct_Pre Rq
du
                          else if a
g forall a. Eq a => a -> a -> Bool
== a
1 then Rq -> Ct_Node
Ct_Edge Rq
du else Rq -> Ct_Node
Ct_Normal Rq
du
            in (Rq
du forall a. Num a => a -> a -> a
* (Rq
60 forall a. Fractional a => a -> a -> a
/ Lseq Rq Rq -> Rq -> Rq
ct_tempo_at Lseq Rq Rq
sq Rq
rq),Ct_Node
nm)
    in forall a b. (a -> b) -> [a] -> [b]
map forall {a} {a}.
(Eq a, Eq a, Num a, Num a) =>
(a, Rq, (a, Rq)) -> (Rq, Ct_Node)
f (forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 [Measure
1::Int ..] [Rq]
mrq [(Measure, Rq)]
dv')

-- | Click track definition.
data Ct =
  Ct
  {Ct -> Measure
ct_len :: Int
  ,Ct -> Tseq Measure Rational_Time_Signature
ct_ts :: [(Measure,T.Rational_Time_Signature)]
  ,Ct -> Tseq Measure Char
ct_mark :: [(Measure,Char)]
  ,Ct -> Lseq (Measure, Measure) Rq
ct_tempo :: T.Lseq (Measure,Pulse) T.Rq
  ,Ct -> (Rq, Measure)
ct_count :: (T.Rq,Int)}
  deriving Measure -> Ct -> ShowS
[Ct] -> ShowS
Ct -> String
forall a.
(Measure -> a -> ShowS)
-> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Ct] -> ShowS
$cshowList :: [Ct] -> ShowS
show :: Ct -> String
$cshow :: Ct -> String
showsPrec :: Measure -> Ct -> ShowS
$cshowsPrec :: Measure -> Ct -> ShowS
Show

-- | Initial tempo, if given.
ct_tempo0 :: Ct -> Maybe T.Rq
ct_tempo0 :: Ct -> Maybe Rq
ct_tempo0 Ct
ct =
    case Ct -> Lseq (Measure, Measure) Rq
ct_tempo Ct
ct of
      (((Measure
1,Measure
1),Interpolation_T
_),Rq
n):Lseq (Measure, Measure) Rq
_ -> forall a. a -> Maybe a
Just Rq
n
      Lseq (Measure, Measure) Rq
_ -> forall a. Maybe a
Nothing

-- | Erroring variant.
ct_tempo0_err :: Ct -> T.Rq
ct_tempo0_err :: Ct -> Rq
ct_tempo0_err = forall a. a -> Maybe a -> a
fromMaybe (forall a. HasCallStack => String -> a
error String
"ct_tempo0") forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ct -> Maybe Rq
ct_tempo0

-- > import Music.Theory.Duration.Ct
-- > import Music.Theory.Time.Seq
-- > let ct = CT 2 [(1,[(3,8),(2,4)])] [(1,'a')] [(((1,1),T.None),60)] undefined
-- > ct_measures ct
ct_measures :: Ct -> [T.Dseq Rational Ct_Node]
ct_measures :: Ct -> [[(Rq, Ct_Node)]]
ct_measures (Ct Measure
n Tseq Measure Rational_Time_Signature
ts Tseq Measure Char
mk Lseq (Measure, Measure) Rq
tm (Rq, Measure)
_) =
    let f :: b -> [(Measure, b)] -> [b]
f b
msg [(Measure, b)]
sq = let ([Measure]
m,[b]
v) = forall a b. [(a, b)] -> ([a], [b])
unzip [(Measure, b)]
sq
                   in if [Measure]
m forall a. Eq a => a -> a -> Bool
== [Measure
1 .. Measure
n]
                      then [b]
v
                      else forall a. HasCallStack => String -> a
error (forall a. Show a => a -> String
show (String
"ct_measures",b
msg,[(Measure, b)]
sq,[Measure]
m,[b]
v,Measure
n))
        msr :: [([Rq], Maybe Char, Maybe (), Mdv)]
msr = forall a b c d. [a] -> [b] -> [c] -> [d] -> [(a, b, c, d)]
zip4
              (forall {b} {b}. (Show b, Show b) => b -> [(Measure, b)] -> [b]
f String
"ts" (forall a b. [a] -> [b] -> [(a, b)]
zip [Measure
1..] (Measure -> Tseq Measure Rational_Time_Signature -> Mdv
ct_rq Measure
n Tseq Measure Rational_Time_Signature
ts)))
              (forall {b} {b}. (Show b, Show b) => b -> [(Measure, b)] -> [b]
f String
"mk" (Measure -> Tseq Measure Char -> Tseq Measure (Maybe Char)
ct_mark_seq Measure
n Tseq Measure Char
mk))
              (forall {b} {b}. (Show b, Show b) => b -> [(Measure, b)] -> [b]
f String
"pre-mk" (Measure -> Tseq Measure Char -> [(Measure, Maybe ())]
ct_pre_mark_seq Measure
n Tseq Measure Char
mk))
              (forall {b} {b}. (Show b, Show b) => b -> [(Measure, b)] -> [b]
f String
"dv" (Measure -> Tseq Measure Rational_Time_Signature -> [(Measure, Mdv)]
ct_dv_seq Measure
n Tseq Measure Rational_Time_Signature
ts))
    in forall a b. (a -> b) -> [a] -> [b]
map (Lseq Rq Rq -> ([Rq], Maybe Char, Maybe (), Mdv) -> [(Rq, Ct_Node)]
ct_measure (Mdv -> Lseq (Measure, Measure) Rq -> Lseq Rq Rq
ct_tempo_lseq_rq (Measure -> Tseq Measure Rational_Time_Signature -> Mdv
ct_mdv_seq Measure
n Tseq Measure Rational_Time_Signature
ts) Lseq (Measure, Measure) Rq
tm)) [([Rq], Maybe Char, Maybe (), Mdv)]
msr

ct_dseq' :: Ct -> T.Dseq Rational Ct_Node
ct_dseq' :: Ct -> [(Rq, Ct_Node)]
ct_dseq' = forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ct -> [[(Rq, Ct_Node)]]
ct_measures

ct_dseq :: Ct -> T.Dseq Double Ct_Node
ct_dseq :: Ct -> Dseq Double Ct_Node
ct_dseq = forall t t' a. (t -> t') -> Dseq t a -> Dseq t' a
T.dseq_tmap forall a. Fractional a => Rq -> a
fromRational forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ct -> [(Rq, Ct_Node)]
ct_dseq'

-- * Indirect

ct_rq_measure :: [[T.Rq]] -> T.Rq -> Maybe Measure
ct_rq_measure :: Mdv -> Rq -> Maybe Measure
ct_rq_measure Mdv
sq Rq
rq = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> a
fst (forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find ((Rq
rq forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem`) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd) (forall a b. [a] -> [b] -> [(a, b)]
zip [Measure
1..] Mdv
sq))

ct_rq_mp :: [[T.Rq]] -> T.Rq -> Maybe (Measure,Pulse)
ct_rq_mp :: Mdv -> Rq -> Maybe (Measure, Measure)
ct_rq_mp Mdv
sq Rq
rq =
    let f :: (a, [Rq]) -> (a, Measure)
f (a
m,[Rq]
l) = (a
m,forall a. a -> Maybe a -> a
fromMaybe (forall a. HasCallStack => String -> a
error String
"ct_rq_mp: ix") (forall a. Eq a => a -> [a] -> Maybe Measure
elemIndex Rq
rq [Rq]
l) forall a. Num a => a -> a -> a
+ Measure
1)
    in forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall {a}. (a, [Rq]) -> (a, Measure)
f (forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find ((Rq
rq forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem`) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd) (forall a b. [a] -> [b] -> [(a, b)]
zip [Measure
1..] Mdv
sq))

ct_rq_mp_err :: [[T.Rq]] -> T.Rq -> (Measure, Pulse)
ct_rq_mp_err :: Mdv -> Rq -> (Measure, Measure)
ct_rq_mp_err Mdv
sq = forall a. a -> Maybe a -> a
fromMaybe (forall a. HasCallStack => String -> a
error String
"ct_rq_mp") forall b c a. (b -> c) -> (a -> b) -> a -> c
. Mdv -> Rq -> Maybe (Measure, Measure)
ct_rq_mp Mdv
sq

ct_mp_to_rq :: [[T.Rq]] -> [((Measure,Pulse),t)] -> [(T.Rq,t)]
ct_mp_to_rq :: forall t. Mdv -> [((Measure, Measure), t)] -> [(Rq, t)]
ct_mp_to_rq Mdv
sq = forall a b. (a -> b) -> [a] -> [b]
map (forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (Mdv -> (Measure, Measure) -> Rq
ct_mp_lookup Mdv
sq))