我至少看到了GHCI does not allow you to disable a warning locally,直到2018年9月(尽管您可以查看整个文件)。
但是也许还有其他方法可以让GHCI知道实际上每个案件都在处理中?
我有时使用的一个惯用法是编写一个函数,其中第一个定义测试某些谓词并返回Left,而其他定义则考虑该操作实际上有意义的参数。每当我这样做时,都会收到“模式匹配不详尽”错误,但实际上我正在检查每种情况。
(有关激发该玩具示例的真实代码,请参见例如pExprToHExpr
here的定义。)
此代码:
{-# LANGUAGE ViewPatterns #-}
data Cowbell = Cowbell
deriving Show
data Instrument = Rattle
| Drums (Maybe Cowbell)
| Violin
| Oboe
deriving Show
pitched :: Instrument -> Bool
pitched Rattle = False
pitched (Drums Nothing) = False
pitched (Drums (Just Cowbell)) = True
pitched Violin = True
pitched Oboe = True
highestPitch :: Instrument -> Either String Float
highestPitch i@(pitched -> False) =
Left $ "Instrument " ++ show i ++ " has no pitch."
highestPitch (Drums (Just Cowbell)) = Right 800
highestPitch Violin = Right 5000
highestPitch Oboe = Right 2000
产生此错误:
example.hs:19:1: warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In an equation for ‘highestPitch’:
Patterns not matched:
Rattle
(Drums Nothing)
在其他情况下,我将细分Instrument
类型:
data Percussive = Rattle | Drums
data Pitched = Violin | Oboe
data Instrument = Percussive Percussive
| Pitched Pitched
但是(在这种虚构的物理学中)一组Drums
可能具有最高音调,如果它包含Cowbell
,那么它既不适合Percussive
也不适合Pitched
类型。
答案 0 :(得分:4)
我会反转哪个功能是“确定的”。即使乐器已调高音调,您仍必须指定一些最高音调,而clean install
提供了您需要知道乐器是否调高音调的所有信息。因此
highestPitch
答案 1 :(得分:2)
GHC不会考虑pitched
的定义来检查详尽性。因此,检查人员实际上忽略了第一个方程,从而引发警告。
实际上,从计算科学的角度来看,GHC无法在一般情况下做出决定,因为存在视图模式时的穷举性尚不确定。充其量来说,GHC可能会使用一些复杂的静态分析,但它只是选择完全忽略pitched
。
要使警告静音,我可以看到两个主要选项。第一种是在末尾添加全部内容。
highestPitch :: Instrument -> Either String Float
highestPitch i@(pitched -> False) =
Left $ "Instrument " ++ show i ++ " has no pitch."
highestPitch (Drums (Just Cowbell)) = Right 800
highestPitch Violin = Right 5000
highestPitch Oboe = Right 2000
highestPitch i =
Left $ "Instrument " ++ show i ++ " has no pitch."
-- we could even use "error", in certain cases
如果遵循这条路线,在这种情况下,我们可以删除第一个方程式。
highestPitch :: Instrument -> Either String Float
highestPitch (Drums (Just Cowbell)) = Right 800
highestPitch Violin = Right 5000
highestPitch Oboe = Right 2000
highestPitch i =
Left $ "Instrument " ++ show i ++ " has no pitch."
或者,我们可以使最后一种情况Oboe
笼统:
highestPitch :: Instrument -> Either String Float
highestPitch i@(pitched -> False) =
Left $ "Instrument " ++ show i ++ " has no pitch."
highestPitch (Drums (Just Cowbell)) = Right 800
highestPitch Violin = Right 5000
highestPitch _oboe = Right 2000 -- must be an Oboe
不过,我不是这种方法的忠实拥护者,因为如果pitched
包含错误,它将以静默方式产生本不应该存在的音调。
实际上,如上面评论中所指出的,还有第三种方法:使用PatternSynonyms
和COMPLETE
编译指示说服GHC取消警告。但是,这更高级。尽管在设计库时肯定有它的用途,但对于这种特定情况,可能有点过大。