您可以使用-Werror
将警告转化为错误。我不知道您是否可以将非详尽模式警告变成错误,对不起!
至于你问题的第三部分:
我有时会编写一些函数,它们往往紧密结合在一起,并且具有在 Haskell 中无法轻松表达的属性。至少其中一些功能往往具有非详尽的模式,通常是“消费者”。例如,在彼此“某种”逆的函数中会出现这种情况。
一个玩具例子:
duplicate :: [a] -> [a]
duplicate [] = []
duplicate (x:xs) = x : x : (duplicate xs)
removeDuplicates :: Eq a => [a] -> [a]
removeDuplicates [] = []
removeDuplicates (x:y:xs) | x == y = x : removeDuplicates xs
现在很容易看出removeDuplicates (duplicate as)
等于as
(只要元素类型在 中 Eq
),但通常duplicate (removeDuplicates bs)
会崩溃,因为有奇数个元素或 2 个连续元素不同。如果它没有崩溃,那是因为bs
最初是由(或可能由)生产的duplicate
!。
所以我们有以下定律(无效的 Haskell):
removeDuplicates . duplicate == id
duplicate . removeDuplicates == id (for values in the range of duplicate)
现在,如果您想在此处防止非详尽模式,您可以removeDuplicates
返回Maybe [a]
,或为丢失的情况添加错误消息。你甚至可以做一些类似的事情
newtype DuplicatedList a = DuplicatedList [a]
duplicate :: [a] -> DuplicatedList a
removeDuplicates :: Eq a => DuplicatedList a -> [a]
-- implementations omitted
所有这些都是必要的,因为在 Haskell 类型系统中你不能轻易地表达“作为一个偶数长度的列表,连续的元素对是相等的”(除非你是 Oleg :)
但是,如果您不导出removeDuplicates
,我认为在这里使用非详尽模式是完全可以的。一旦您导出它,您将失去对输入的控制,并且必须处理丢失的案例!