The trick for your particular problem would be to use the sepBy
family of functions. You're parsing lists of numbers separated by commas, which is exactly what sepBy
is for. A list of verses has the following properties: there has to be at least one verse number and there is a trailing comma. Combining the two, we realize we need the sepEndBy1
function. These functions are usually written in an infix position, so your code would look something like this:
verseNrs = verseNr `sepEndBy1` (spaces >> char ',' >> spaces)
I don't think you need to change anything else to get the code to work.
A couple of other minor style notes: you have some unnecessary parentheses. This isn't important, it just annoys me personally. E.g. in case ... of
you do not need parens around the ...
bit. Also, you do not need the type signature when you use read
--the compiler can infer the type. That is, since verseNrs
returns [Int]
, it's completely clear both to the compiler and to me that read n
produces an Int
. There is no need to say it explicitly.