2013-07-07 55 views
3

分別具有類型爲'string','string option'和'int option'的三個屬性'a','b'和'c'的類型提供程序。怪異類型提供程序中的無行爲

當我有「」一個實例,無,並在這些屬性的一些1,失敗:

(row1.a, row1.b, row1.c) |> should equal ("", None, Some 1) 

但所有這些做工精細:

row1.a |> should equal "" 

row1.b |> should equal None 

row1.c |> should equal (Some 1) 

("", None, Some 1) |> should equal ("", None, Some 1) 

這怎麼可能?什麼可以使b中的None與其他None不同?編譯後,None只是一個null,在.Net中可以有兩個null值不同?

元組具有結構相同性,就像大多數F#類型一樣,所以它應該可以工作。 我得到一個NUnit.Framework.AssertionException與消息:

Expected: <(, , Some(1))> 
But was: <(, , Some(1))> 

NUnit的只是調用.Equals,所以這就是問題的所在。

這也將失敗:

(row1.a, row1.b, row1.c).Equals(("", None, Some 1)) |> should equal true 

row1運行時類型爲System.Tuple<string,Microsoft.FSharp.Core.FSharpOption<string>,Microsoft.FSharp.Core.FSharpOption<int>>,所以即使這個理論上應該工作:

row1 |> should equal ("", None, Some 1) 

而事實上它時,有一個在元組沒有None不。

我不能用任何其他類型提供程序重現此行爲。

+0

嗯。你在比較'string * string option * int option'到'string * obj option * int option'嗎? – kvb

+0

如果我這樣做:在(row1.a,row1.b,row1.c)|>中的let t =(「」,None,Some 1)應該等於t'工具提示說't'是一個'string * '一個選項* int選項',所以它應該工作 –

+0

好吧,我總是假設問題是在左側,而不是在右側,但在您的評論後,我意識到這兩個:'(row1.a,row1 .b,row1.c)|>應該等於(「」,選項。無,有些1)'和這個:'row1 |>應該等於(「」,選項。無,有些1)'工作。謝謝 –

回答

5

我們已經通過這幾次被咬的,所以我們對這個創造a specific note

FsUnit使用型式試驗來實現其DSL。類型推斷不適用於此DSL,因此請確保兩個比較值屬於相同類型。

例如,對於一些通用的值,如TrueFalse,等等,你需要指定其類型(如formula<fol>.Trueformula<fol>.False等),否則這些值將作爲obj類型進行比較。

如果你看看how FsUnit is implemented,它不是類型安全的。我相信Jack P.'s pull request是讓FsUnit更安全的一步。這似乎是改進FsUnit的一個領域。

+1

我對空列表'[]'有同樣的問題。鍵入註解('([]:list ''在我的情況下)解決了它。 –