Haskell 非穷举模式
鉴于我有以下代码:Haskell 非穷举模式,haskell,non-exhaustive-patterns,Haskell,Non Exhaustive Patterns,鉴于我有以下代码: 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 resolveAscendingInterva
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
resolveAscendingInterval工作正常,但当我运行resolveAscendingInterval时,我得到:
函数ResolveDowningInterval中的非穷举模式
他们的代码和逻辑非常相似,所以我不知道哪里出了问题
另一件事:有没有其他方法可以在不使用递归的情况下实现此行为?这只是一个输入错误。请注意,
resolvedrendingIInterval
是与resolvedrendingInterval
不同的函数。摆脱那些多余的I
编辑:考虑以下略微不安全的代码:
resolveDecendingInterval interval note = toEnum (fromEnum note - interval)
这是一个局部函数-当间隔太大时,它将失败,我们对超出范围的内容调用toEnum
。您可以通过max(fromnum(minBound::Note))等代码钳制范围。最小值(从枚举(maxBound::Note))
。但也许有一种更聪明的方法我只是不想马上离开
另一种方法是通过
rem interval(fromnum note)
钳制间隔
,但是当note被单独分割时,您需要处理这种情况。您的'resolvedgendinterval'名称中有一个输入错误,因此该函数没有通用的情况。天哪,抱歉这个愚蠢的问题,FP complete VI的模式游标在视觉模式上获得了一个传统字符。GHC应该在上面的代码上发出两个警告:关于非穷举函数,以及关于缺少类型签名的命名错误的函数。如果没有启用警告,则启用警告--它们可能非常有用。