-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMeasureSiblingMerge.hs
More file actions
38 lines (26 loc) · 1.07 KB
/
MeasureSiblingMerge.hs
File metadata and controls
38 lines (26 loc) · 1.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
{-# OPTIONS_GHC -fno-warn-name-shadowing #-}
module MeasureSiblingMerge (measureSiblingMerge)
where
import qualified Measure as M ( M(..), E(..), m, d, r, l)
converge :: (a -> a -> Bool) -> [a] -> a
converge p (x:ys@(y:_))
| p x y = y
| otherwise = converge p ys
converge _ _ = error "converge"
measureSiblingMerge :: M.M -> M.M
measureSiblingMerge (M.M ts metro e) = r
where r = M.m ts metro $ (converge (==) . iterate eltSiblingMerge) e
eltSiblingMerge :: M.E -> M.E
eltSiblingMerge l@M.L{} = l
eltSiblingMerge r@M.R{} = r
eltSiblingMerge (M.D dur factor children) =
M.d dur factor $ foldr mcons [] merged_children
where merged_children = map eltSiblingMerge children
mcons :: M.E -> [M.E] -> [M.E]
mcons (M.R dur _) (M.R dur' _ : es) = M.r (dur + dur'):es
mcons (M.L dur True _ ns exps) (M.L dur' tie _ _ _ : es) = M.l (dur + dur') tie ns exps : es
mcons l@M.L{} es = l:es
mcons r@(M.R _ _) es = r:es
mcons (M.D dur factor children) (M.D dur' factor' children' : es)
| factor == factor' = M.d (dur + dur') factor (children ++ children') : es
mcons a b = a:b