Неисчерпывающие закономерности

Учитывая, что у меня есть следующий код:

data Note = C | Db | D | Eb | E | F | Gb | G | Ab | A | Bb | B
      deriving (Show, Eq, Ord, Enum)

next :: Note -> Note
next B = C
next n = succ n

previous :: Note -> Note
previous C = B
previous n = pred n

resolveAscendingInterval :: Int -> Note -> Note
resolveAscendingInterval 0 note = note
resolveAscendingInterval interval note = resolveAscendingInterval (interval -1) (next note)

resolveDescendingInterval :: Int -> Note -> Note
resolveDescendingInterval 0 note = note
resolveDescendingIInterval interval note = resolveDescendingIInterval (interval -1) (previous note)

main :: IO ()
    main = do
    print $ resolveAscendingInterval 3 C
    print $ resolveDescendingInterval 3 C

resolAscendingInterval работает нормально, но когда я запускаю resolDescendingInterval, я получаю:

Неполные шаблоны в функции resolDescendingInterval

Их код и логика очень похожи, поэтому я понятия не имею, что не так

Другое дело: есть ли другой способ добиться этого поведения без рекурсии?

1 ответ

Это просто опечатка. уведомление resolveDescendingIInterval это другая функция от resolveDescendingInterval, Избавиться от этого лишнего I,

РЕДАКТИРОВАТЬ: рассмотрим следующий слегка небезопасный код:

resolveDecendingInterval interval note = toEnum (fromEnum note - interval)

Это частичная функция - она ​​потерпит неудачу, когда интервал слишком большой, и мы вызываем toEnum на что-то вне диапазона. Вы можете зафиксировать диапазон с помощью кода, такого как max (fromEnum (minBound :: Note)) . min (fromEnum (maxBound :: Note)), Но, вероятно, есть более разумный способ, которым я просто не думаю сразу.

Одной из альтернатив будет зажим interval с помощью rem interval (fromEnum note) но тогда вам нужно будет обработать случай, когда примечание является minBound отдельно.

Другие вопросы по тегам