3

タイプ 'string'、'string option' および 'int option' の 3 つのプロパティ 'a'、'b'、および 'c' を持つタイプ プロバイダがあります。

これらのプロパティに ""、None、および Some 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 で 2 つの 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

のランタイム タイプrow1System.Tuple<string,Microsoft.FSharp.Core.FSharpOption<string>,Microsoft.FSharp.Core.FSharpOption<int>>であるため、これでも理論上は機能するはずです。

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

実際None、タプルに no がない場合はそうです。

この動作は、型プロバイダー以外では再現できません。

4

1 に答える 1

5

私たちはこれに何度か悩まされてきたので、これについて具体的なメモを作成します。

FsUnit は型テストを使用して DSL を実装します。この DSL では型推論が機能しないため、比較される 2 つの値が同じ型に属していることを確認してください。

たとえば、True、などの一般的な値の場合、その型を ( 、などとして)False指定する必要があります。そうしないと、これらの値は 型として比較されます。formula<fol>.Trueformula<fol>.Falseobj

FsUnit の実装方法を見ると、実際には型安全ではありません。Jack P. のプル リクエストは、 FsUnitをより型安全にするための一歩だと思います。FsUnitを改善する領域のようです。

于 2013-07-07T21:36:40.403 に答える