0

我想知道人们如何在 SML/NJ 编译器中处理非详尽的匹配警告。例如,我可以定义一个数据类型

datatype DT = FOO of int | BAR of string

然后有一个我知道只需要 FOO 的功能

fun baz (FOO n) = n + 1

编译器会给出警告

标准输入:1.5-1.24 警告:匹配非详尽
          FOO n => ...
val baz = fn : DT -> int

我不想看到我故意做的不完整匹配的警告,因为我必须扫描输出以找到可能实际上是错误的警告。我可以这样写函数

fun baz (FOO n) = n + 1 
  | baz _ = raise Fail "baz"

但这会使代码混乱。人们在这种情况下通常会做什么?

4

5 回答 5

3

您可以设置以下编译器标志来配置非详尽匹配警告的警告级别:

  • Compiler.Control.MC.matchNonExhaustiveWarn
  • Compiler.Control.MC.matchNonExhaustiveError

如果这两个都设置为 false,则不会生成警告。不幸的是,这将关闭此错误的所有实例的警告,这可能不是您想要的,因为它将删除此保护措施。

(注意:您只需在代码中将这些设置为 false)

更多信息可以在这里找到。第 46 项具体描述了您的警告。

于 2010-04-04T16:07:33.803 回答
3

正如丹尼尔所说,您可以关闭警告,但我不建议这样做。

最好可以调整数据类型,以便函数能够在允许的整个值范围内进行操作。第二好的方法是继续并用错误“弄乱”代码,以明确正在发生的事情(并允许更有意义的运行时错误)。

于 2010-04-04T16:17:36.993 回答
2

您必须涵盖所有情况,以便决定该函数如何处理其整个域,或者接受警告。最后一种选择是首先修改您通过函数提供的值,以便在调用者中完成解构。

于 2010-04-04T15:32:28.503 回答
1

我认为如果你经常这样做,你需要重新考虑你的数据类型。如果 Foo 和 Baz 不是同一类型的对象,为什么要将它们组合在一个数据类型中?如果它们是构造同一对象的不同方式,那么您会期望在 Foo 上工作的函数也能够在 Baz 上做一些明智的事情。如果您有一个带有构造函数 Car 和 Bike 的 Vehicle 类型,但您只想对 Cars 进行一些操作,如果您的代码很大,那么正确的做法可能是分离出 Car 的定义并更改您正在使用的所有位置车辆,但希望只有 Car 直接使用 Car。

于 2010-04-20T10:23:41.650 回答
1

就像其他答案所说的那样,更改数据类型以产生详尽的匹配会更干净。在这种情况下,您可能会更改DT类型,或者您可以将返回类型从baz. 例如:

datatype DT = FOO of int | BAR of string
fun baz (FOO n) = SOME (n + 1)
  | baz _       = NONE

然后baz具有类型val baz = fn : DT -> int option,您不必担心处理由baz.

于 2010-05-16T18:10:19.560 回答