a problem I can't solve simply

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.

Ooops I meant to post this to the beginner's list. I'll wait to see if someone here responds, then repost it on the beginner's list.

You have separate streams of overlapping events, so if you merge them
into one stream your life will be easier:
mergeOn key = Data.List.Ordered.mergeBy (Data.Ord.comparing key)
computeEndMsr begin = findEnd begin . skip . mergeOn fst
where
-- drop until the begin measure
skip = dropWhile ((
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.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
participants (2)
-
Dennis Raddle
-
Evan Laforge