lower i (N (l,o,a,h,d)) = N (pred' i l, o - octChange, a + offset, h, d)
  where notesToOctBorder = fromIntegral . length . takeWhile (/=C) . iterate (pred' 1) $ l
        nonOctaveNotes = i `mod` 7
        numOctavesAdded = i `div` 7
        octaveBorderCrossed = nonOctaveNotes > notesToOctBorder
        oneSteps = fromIntegral . length . filter (`elem`[B,E]) . map (`pred'` l) $ [1..nonOctaveNotes]
        offset = oneSteps + 2*(nonOctaveNotes - oneSteps) + 12*numOctavesAdded
        octChange = numOctavesAdded + if octaveBorderCrossed then 1 else 0
lower i (N (l,o,a,h,d)) = N (pred' i l, o - octChange, a + offset, h, d)
  where notesToOctBorder = fromIntegral . length . takeWhile (/=C) . iterate (pred' 1) $ l
        nonOctaveNotes = i `mod` 7
        numOctavesAdded = i `div` 7
        octaveBorderCrossed = nonOctaveNotes > notesToOctBorder
        oneSteps = fromIntegral . length . filter (`elem`[B,E]) . map (`pred'` l) $ [1..nonOctaveNotes]
        offset = oneSteps + 2*(nonOctaveNotes - oneSteps) + 12*numOctavesAdded
        octChange = numOctavesAdded + if octaveBorderCrossed then 1 else 0
lower i (N (l,o,a,h,d)) = N (pred' i l, o - octChange, a + offset, h, d)
  where notesToOctBorder = fromIntegral . length . takeWhile (/=C) . iterate (pred' 1) $ l
        nonOctaveNotes = i `mod` 7
        numOctavesAdded = i `div` 7
        octaveBorderCrossed = nonOctaveNotes > notesToOctBorder
        oneSteps = fromIntegral . length . filter (`elem`[B,E]) . map (`pred'` l) $ [1..nonOctaveNotes]
        offset = oneSteps + 2*(nonOctaveNotes - oneSteps) + 12*numOctavesAdded
        octChange = numOctavesAdded + if octaveBorderCrossed then 1 else 0