<div dir="ltr">I have a problem that doesn't seem hard to state but I can't seem to solve without a bunch of complex code.<div><br></div><div>This relates to my musical score playback. In using it to play music, I don't always want to play back the entire source musical document, but rather play a range of measures. So I might give a command to my app like "play 1-3" which means play measures 1 through 3.</div><div><br></div><div>There is a time saving feature, which is that I can type "play 10" which means start the playback at measure 10 and continue until the first occurrence of two empty measures. This is a common use case.</div><div><br></div><div>So I have to write a function that takes a start measure and computes the end measure by scanning for two empty measures. </div><div><br></div><div>Let's say for simplicity's sake that we'll forget about "measures" and just say that notes have a start time and end time, which will be integers. </div><div><br></div><div>type Note = (Int,Int)</div><div><br></div><div>A musical score can have several individual staves (notes for individual instruments), so it will look like this:</div><div><br></div><div>type Staff = [Note]</div><div><br></div><div>type Score = [Staff]</div><div><br></div><div>I need to write a function as follows</div><div><br></div><div>computeEndMsr :: Int -> Score -> Int</div><div>computeEndMsr beginMsr score = ...</div><div><br></div><div>Some examples:</div><div><br></div><div>Here's a score with just one staff, to give you an idea.</div><div><br></div><div>score1 = [ [(1,3), (2,4), (7,10)] ]</div><div><br></div><div>-- In the following case a two-unit gap is found at units 5 and 6.</div><div>computeEndMsr 1 score1 = 4</div><div><br></div><div>computeEndMsr 5 score1 = should throw an error indicating that a gap was found immediately and no actual notes were included</div><div><br></div><div>-- In the following case, the maximum unit of any note is 10, so that is what is computed</div><div>computeEndMsr 6 score1 = 10 </div><div><br></div><div>-- This case illustrates how it's okay if the computed end measure is equal to the begin msr</div><div>computeEndMsr 10 score1 = 10</div><div><br></div><div>computeEndMsr 11 score1 = should throw an error indicating that the given begin msr is past the end of any note in the score</div><div><br></div><div>This example has only one staff, but a score can have multiple staves. Also the timing and duration of notes can overlap, either on one staff or across multiple staves.</div></div>