SML/NJ 不完全匹配

发布于 2024-08-27 14:57:31 字数 508 浏览 2 评论 0原文

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

datatype DT = FOO of int | BAR of string

,然后有一个我知道只需要 FOO 的函数

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"

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

I wonder how people handle nonexhaustive match warnings in the SML/NJ compiler. For example, I may define a datatype

datatype DT = FOO of int | BAR of string

and then have a function that I know only takes FOOs

fun baz (FOO n) = n + 1

The compiler will give a warning

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

I don't wanna see warnings for incomplete matches I did on purpose, because then I have to scan through the output to find a warning that might actually be a bug. I can write the function like this

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

but this clutters the code. What do people usually do in this situation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

剑心龙吟 2024-09-03 14:57:31

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

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

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

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

更多信息可以在此处。第 46 项具体描述了您的警告。

You can set the following compiler flags to configure the warning level of non-exhaustive match warnings:

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

If both of these are set to false, there will be no warning generated. Unfortunately, this will turn off warnings for all instances of this error, which is probably not what you want since it will remove this safeguard.

(Note: You just set these to false in your code)

More info can be found here. Item 46 describes your warning specifically.

小鸟爱天空丶 2024-09-03 14:57:31

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

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

As Daniel mentioned, you can turn off the warning, but I would not recommend that.

It is best if you can adjust your data types so that functions are able to operate over the entire range of values allowed. Second best is to go ahead and "clutter" the code with errors to make it explicit what's happening (and allow more meaningful run-time errors).

愁以何悠 2024-09-03 14:57:31

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

You've got to either cover all the cases so that you've decided how the function handles the entirety of its domain, or live with the warning. The final alternative is to revise what values you feed through the function in the first place so that the deconstruction is done in the caller.

愿与i 2024-09-03 14:57:31

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

I think if you do this a lot you need to rethink your datatypes a bit. Why are you grouping Foo and Baz together in one datatype if they are not the same sort of object? If they are different ways of constructing the same object, then you would expect that a function which works on Foo would be able to do something sensible on Baz as well. If you have a type Vehicle with constructors Car and Bike, but you only want to do some operation on Cars, if your code is large the right thing to do might to separate out the definition of Car and change all the places where you are using Vehicles but expecting only Car to use Car directly.

天涯离梦残月幽梦 2024-09-03 14:57:31

就像其他答案所说,更改数据类型以产生详尽的匹配会更干净。在这种情况下,您可以更改 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 引发的错误。

Like the other answers say, it's cleaner to change your datatypes to produce an exhaustive match. In this case, you might change the DT type, or you could change the return type from baz. For example:

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

Then baz has the type val baz = fn : DT -> int option and you don't have to worry about handling errors raised by baz.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文