代码之家  ›  专栏  ›  技术社区  ›  dimvar

SML/NJ不完全匹配

sml
  •  0
  • dimvar  · 技术社区  · 15 年前

    我想知道人们如何处理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 回复  |  直到 15 年前
        1
  •  3
  •   Daniel Brotherston    15 年前

    可以设置以下编译器标志以配置非完全匹配警告的警告级别:

    • compiler.control.mc.matchnonexhaustivwarn(编译器.control.mc.matchnonexhaustivwarn)
    • compiler.control.mc.matchnonexhaustiveerror(编译器.control.mc.matchnonexhaustiveerror)

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

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

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

        2
  •  3
  •   Michael Ekstrand    15 年前

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

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

        3
  •  2
  •   Donal Fellows    15 年前

    您必须覆盖所有的情况,以便决定函数如何处理其整个域,或者活在警告中。最后一种选择是首先修改通过函数输入的值,以便在调用程序中进行解构。

        4
  •  1
  •   Nicholas Wilson    15 年前

    我认为如果你经常这样做,你需要重新考虑一下你的数据类型。如果foo和baz不是同一类型的对象,为什么要将它们分组在一个数据类型中?如果它们是构造同一对象的不同方法,那么在foo上工作的函数也可以在baz上做一些明智的事情。如果你有一辆装有汽车和自行车的类型车,但你只想对汽车做一些操作,如果你的代码很大,正确的做法可能是分离出汽车的定义,改变你使用汽车的所有地方,但只期望汽车直接使用汽车。

        5
  •  1
  •   snim2    15 年前

    像其他答案所说的那样,更改数据类型以生成完全匹配更为简单。在这种情况下,您可以更改 DT 类型,或者可以更改返回类型 baz . 例如:

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

    然后 巴兹 具有类型 val baz = fn : DT -> int option 你不必担心处理 巴兹