Возможно, вы захотите использовать GenParser с состоянием, содержащим текущие номера разделов в виде списка в обратном порядке, поэтому раздел 1.2.3 будет представлен как [3,2,1], и, возможно, длина списка, чтобы избежать неоднократно считая это. Что-то вроде
data SectionState = SectionState {nums :: [Int], depth :: Int}
Тогда сделайте так, чтобы ваши действия синтаксического анализатора возвращали тип "GenParser Char SectionState a". Вы можете получить доступ к текущему состоянию в действиях вашего парсера, используя «getState» и «setState». Когда вы получите ряд «-» в начале строки, подсчитайте их и сравните с «глубиной» в состоянии, соответствующим образом управляйте списком «nums», а затем выведите «nums» в обратном порядке (я предлагаю сохранить nums в обратном порядке, потому что большую часть времени вы хотите получить доступ к наименее значимому элементу, поэтому поместить его в начало списка одновременно проще и эффективнее).
См. Text.ParserCombinators.Parsec.Prim для получения подробной информации о GenParser. Более обычным типом Parser является просто «type Parser a = GenParser Char () a» Вы, вероятно, хотите сказать
type MyParser a = GenParser Char SectionState a
где-то рядом с началом вашего кода.