非穷举模式 [英] Non-exhaustive patterns

查看:81
本文介绍了非穷举模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

鉴于我有以下代码:

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可以正常工作,但是当我运行resolveDescendingInterval时,我得到:

resolveAscendingInterval works fine, but when I run resolveDescendingInterval I get:

resolveDescendingInterval函数中的非穷举模式

他们的代码和逻辑非常相似,所以我不知道出什么毛病了

Their code and logic are very similar, so I don't have a clue of whats wrong

另一件事:是否有另一种方法可以实现这种行为而无需递归?

Another thing: Is there another way to achieve this behavior without recursion?

推荐答案

这只是一个错字.注意resolveDescendingIInterval是与resolveDescendingInterval不同的功能.摆脱多余的I.

This is just a typo. Notice resolveDescendingIInterval is a different function from resolveDescendingInterval. Get rid of that extra I.

考虑以下稍微不安全的代码:

Consider the following slightly unsafe code:

resolveDecendingInterval interval note = toEnum (fromEnum note - interval)

这是一个部分函数-如果间隔太大,并且在超出范围的地方调用toEnum,它将失败.您可以通过诸如max (fromEnum (minBound :: Note)) . min (fromEnum (maxBound :: Note))之类的代码来限制范围.但是,也许我不打算立即考虑一种更聪明的方法.

This is a partial function - it will fail when the interval is too large and we call toEnum on something out of range. You can clamp the range via code such as max (fromEnum (minBound :: Note)) . min (fromEnum (maxBound :: Note)). But there's probably a smarter way I'm just not thinking off immediately.

一种选择是通过rem interval (fromEnum note)夹住interval,但是当音符分别为minBound时,您将需要处理这种情况.

One alternative would be to clamp the interval via rem interval (fromEnum note) but then you'll need to handle the case when note is minBound separately.

这篇关于非穷举模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆