我开始使用FsUnit来测试F#代码.它可以用F#样式表达断言,例如:
[<Test>]
member this.``Portugal voted for 23 countries in 2001 Eurovision contest``() =
this.totalVotes
|> getYearVotesFromCountry "Portugal" 2001
|> Seq.length
|> should equal 23
Run Code Online (Sandbox Code Playgroud)
注意我应该从FsUnit得到"应该等于23".以下是FsUnit如何定义它:
let equal x = new EqualConstraint(x)
对于浮点数,它并不那么简单.我必须使用EqualConstraint和Within方法.它自然适合C#:
Assert.That(result).Is.EqualTo(1).Within(0.05);
Run Code Online (Sandbox Code Playgroud)
当然我希望能用F#写:
result |> should equal 1 within 0.05
Run Code Online (Sandbox Code Playgroud)
但这不起作用.我最终定义了一个新函数:
let almostEqual x = (new EqualConstraint(x)).Within(0.01)
Run Code Online (Sandbox Code Playgroud)
或者如果我想参数化精度,我可以将其指定为第二个参数:
let equalWithin x y = (new EqualConstraint(x)).Within(y)
Run Code Online (Sandbox Code Playgroud)
但它们都不漂亮.我想以更自然的方式为F#定义"内部"函数,因此它可以与相等的一起使用.F#不支持方法重载,因此看起来我无法以这种方式定义它,因此"相等"可以单独使用或与"内部"一起使用.
有任何想法吗?
Tom*_*cek 12
这是一个有趣的问题!我认为你不能within 0.05以should equal任何方式附加现有的定义.为此,您需要向should函数添加参数,但需要在库中具有固定数量的参数.
在F#中优雅地写这个的一种方法是创建自定义运算符+/-.请注意,您仍然需要使用括号,但它看起来很整洁:
0.9 |> should equal (1.0 +/- 0.5)
Run Code Online (Sandbox Code Playgroud)
运算符只是构造一个需要在equal函数中显式处理的特殊类型的值.这是实施:
type Range = Within of float * float
let (+/-) (a:float) b = Within(a, b)
let equal x =
match box x with
| :? Range as r ->
let (Within(x, within)) = r
(new EqualConstraint(x)).Within(within)
| _ ->
new EqualConstraint(x)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
618 次 |
| 最近记录: |