I have a problem that doesn't seem hard to state but I can't seem to solve without a bunch of complex code.

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.

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.

So I have to write a function that takes a start measure and computes the end measure by scanning for two empty measures. 

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. 

type Note = (Int,Int)

A musical score can have several individual staves (notes for individual instruments), so it will look like this:

type Staff = [Note]

type Score = [Staff]

I need to write a function as follows

computeEndMsr :: Int -> Score -> Int
computeEndMsr beginMsr score = ...

Some examples:

Here's a score with just one staff, to give you an idea.

score1 = [ [(1,3), (2,4), (7,10)] ]

-- In the following case a two-unit gap is found at units 5 and 6.
computeEndMsr 1 score1 = 4

computeEndMsr 5 score1 = should throw an error indicating that a gap was found immediately and no actual notes were included

-- In the following case, the maximum unit of any note is 10, so that is what is computed
computeEndMsr 6 score1 = 10 

-- This case illustrates how it's okay if the computed end measure is equal to the begin msr
computeEndMsr 10 score1 = 10

computeEndMsr 11 score1 = should throw an error indicating that the given begin msr is past the end of any note in the score

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.