这是一个后续行动 我为什么得到"非详尽模式在功能..."我引用我的Haskell子串的功能?

我的理解是,使用 -Wall,GHC可以警告对非详尽无遗的模式。我想知道什么是背后的原因不让它编译时间错误的默认情况下给予,它总是能够明确定义的部分功能:

f :: [a] -> [b] -> Int
f [] _  = error "undefined for empty array"
f _ []  = error "undefined for empty array"
f (_:xs) (_:ys) = length xs + length ys

问题不是全康特定的。

这是因为...

  • 没有人想要强制执行Haskell编译器,来执行这样的分析?
  • 非详尽模式搜索可以找到一些但不是所有的情况?
  • 部分规定的职能都被认为是合法的并且使用的往往不够不对这种建造所示上面?如果是这种情况下,你可以向我解释为什么非详尽模式,是有用的/合法的?
有帮助吗?

解决方案

在有些情况下你不会介意的模式相匹配是非详尽无遗的。例如,虽然这可能不是最佳的执行,我不认为这将帮助,如果它没有编译:

fac 0 = 1
fac n | n > 0 = n * fac (n-1)

这不是详尽无遗的(负数字不符合任何情况下)并不真正的问题的典型使用情况的因素的功能。

此外,它可能不是通常有可能决定编译器,如果一个模式匹配是详尽无遗:

mod2 :: Integer -> Integer
mod2 n | even n = 0
mod2 n | odd n  = 1

这里所有的情况应包括在内,但编译可能不能检测到它。自卫队可以任意复杂,编译器,不能总是决定,如果该模式是详尽无遗的。当然,这个例子中将可更好地被写的 otherwise, 但我认为它也应汇编在其目前的形式。

其他提示

你可以使用 -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系统类型(除非你是奥列格:)

但如果你不出口 removeDuplicates 我认为这是完全好使用非详尽无遗的模式在这里。只要你做出了它,你就会失去控制投入和将要处理失踪的情况下!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top