SML / NJ不完全匹配

时间:2010-04-04 15:27:16

标签: sml

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

datatype DT = FOO of int | BAR of string

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

fun baz (FOO n) = n + 1

编译器会发出警告

stdIn:1.5-1.24 Warning: match nonexhaustive
          FOO n => ...
val baz = fn : DT -> int

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

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

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

5 个答案:

答案 0 :(得分:3)

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

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

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

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

可以找到更多信息here。第46项具体描述了你的警告。

答案 1 :(得分:3)

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

最好能够调整数据类型,以便函数能够在允许的整个值范围内运行。第二个最好的方法是继续使用错误“混乱”代码,使其明确发生了什么(并允许更有意义的运行时错误)。

答案 2 :(得分:2)

您必须覆盖所有案例,以便您已决定该函数如何处理其整个域,或者使用警告。最后一种方法是首先修改你通过函数提供的值,以便在调用者中完成解构。

答案 3 :(得分:1)

我认为如果你这么做很多,你需要重新思考一下你的数据类型。如果它们不是同一种对象,为什么要将Foo和Baz组合在一个数据类型中?如果它们是构造同一个对象的不同方式,那么你会期望在Foo上运行的函数也能够在Baz上做一些合理的事情。如果你有一个带有构造函数Car和Bike的类型的Vehicle,但你只想在Cars上做一些操作,如果你的代码很大,那么正确的做法可能是将Car的定义分开并改变你使用的所有地方车辆,但期望只有汽车直接使用汽车。

答案 4 :(得分: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引发的错误。