
Daniel Fischer wrote:
import Data.Function (on) import Data.List
convert namedStaffs = map timeVertical verticals where nameTimedChords (name,tcs) = [(time,name,chord) | (time, chord) <- tcs] timedNamedChords = sort . foldr merge [] . map nameTimedChords $ namedStaffs fst3 (x,_,_) = x verticals = groupBy ((==) `on` fst3) timedNamedChords timeVertical v@((t,_,_):_) = (t,[(name,chord) | (_,name,chord) <- v])
?
Hi Daniel, Thanks, that is nice and I will learn a lot by studying it. However, a problem. It will be a big benefit to do this lazily because I only need to extract as many verticals as necessary to fit on one page of layout. I realized, as you did, that it would simplify things to care only about NamedTimedChords: type NamedTimedChord = (Name,Time,Chord) Even though there is some redundancy to have every entry carry along its name and time, it is worth it for simplifying things. Here's what I have, to do this lazily and now caring only about NamedTimedChords: toVerticals :: [[NamedTimedChord]] -> [[NamedTimedChord]] toVerticals [] = [] toVerticals staves = firstVertical : toVerticals remainder where time3 (_,time,_) = time firstVertT = minimum $ map (time3 . head) staves usingStaves = [ s | s <- staves, time3 (head s) == firstVertT ] notUsingStaves = [ s | s <- staves, time3 (head s) /= firstVertT ] firstVertical = map head usingStaves remainder = leftOfUsing ++ notUsingStaves leftOfUsing = filter (not . null) (map tail usingStaves)