2010-04-04 35 views
0

我想知道人們如何處理SML/NJ編譯器中的非窮舉匹配警告。例如,我可以定義一個數據類型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" 

但這會使代碼雜亂無章。人們通常在這種情況下做什麼?

回答

3

您可以設置以下編譯器標誌配置非詳盡的匹配警告的警告級別:

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

如果這兩個都設置爲false,則不會生成警告。不幸的是,這將關閉此錯誤的所有實例的警告,這可能不是您想要的,因爲它會移除此安全措施。

(注:您只要在代碼中設置這些爲false)

更多信息,可以發現here。第46項具體描述了你的警告。

2

您必須覆蓋所有的情況,以便您確定函數如何處理其整個域或遵從警告。最後的選擇是首先修改通過函數提供的值,以便在調用者中完成解構。

3

正如丹尼爾所說,你可以關掉警告,但我不會推薦。

如果您可以調整數據類型,以便函數能夠在允許的整個值範圍內運行,那麼最好。其次,最好是繼續前進,並用錯誤「混亂」代碼,使其明確發生了什麼(並允許更有意義的運行時錯誤)。

+0

你能否提供一些關於如何更改編譯器標誌的信息? – 2014-02-06 00:15:51

1

我想如果你這麼做了很多,你需要重新考慮一下你的數據類型。爲什麼將Foo和Baz分組在一起,如果它們不是同一類型的對象?如果他們是構建同一個對象的不同方式,那麼你會期望在Foo上工作的函數也能夠在Baz上做一些明智的事情。如果你有一個帶有構造函數Car和Bike的類型Vehicle,但你只想在Cars上做一些操作,如果你的代碼很大,那麼正確的做法可能是將Car的定義分開並且改變你使用的所有地方車輛,但期望只有汽車直接使用汽車。

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引發的錯誤。