【问题标题】:SML/NJ incomplete matchSML/NJ 不完全匹配
【发布时间】:2010-05-17 02:10:19
【问题描述】:

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

datatype DT = FOO of int | BAR of string

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

fun baz (FOO n) = n + 1

编译器会给出警告

stdIn:1.5-1.24 警告:匹配不完整
          FOO n => ...
val baz = fn : DT -> int

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

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

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

【问题讨论】:

    标签: sml


    【解决方案1】:

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

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

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

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 您能否提供一些有关如何更改编译器标志的信息?
      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            猜你喜欢
            • 2014-09-30
            • 2018-10-05
            • 1970-01-01
            • 2010-12-20
            • 1970-01-01
            • 2011-11-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多