F# FsUnit与浮点数的相等性检验
我开始使用FsUnit测试F#代码。它可以用F#风格表达断言,例如:F# FsUnit与浮点数的相等性检验,f#,nunit,fsunit,F#,Nunit,Fsunit,我开始使用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 当然
[<Test>]
member this.``Portugal voted for 23 countries in 2001 Eurovision contest``() =
this.totalVotes
|> getYearVotesFromCountry "Portugal" 2001
|> Seq.length
|> should equal 23
当然,我希望能够用F#写:
但这是行不通的。我最终定义了一个新函数:
let almostEqual x = (new EqualConstraint(x)).Within(0.01)
或者,如果要参数化精度,可以将其指定为第二个参数:
let equalWithin x y = (new EqualConstraint(x)).Within(y)
但他们都不漂亮。我想用一种更自然的方式为F#定义“in”函数,这样它就可以与equal一起使用。F#不支持方法重载,所以看起来我不能这样定义它,“equal”可以单独使用,也可以与“in”一起使用
有什么想法吗?术语说明:F#支持方法重载;它不支持重载let绑定函数(模块中定义的“free”函数)
例如,可以使用点使其should.equal
,以便equal
是should
对象上的一个方法,可以重载该方法。尽管这仍然没有帮助,因为你不能过度使用陈词滥调。嗯
好吧,我没有什么有用的。就我个人而言,我不喜欢库中的这种语法糖。这是一个有趣的问题!我不认为您可以在0.05以内将
附加到的现有定义中,而应以任何方式等于。为此,您需要将参数添加到should
函数中,但这需要库中有固定数量的参数
用F#优雅地编写这个函数的一种方法是创建自定义操作符+/-
。请注意,仍然需要使用括号,但看起来很整洁:
0.9 |> should equal (1.0 +/- 0.5)
运算符只构造需要在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)
你说得对,布莱恩。我的意思是,当然是让约束函数。我喜欢这种糖。我认为这在F#中很重要。哇!真是太需要了!谢谢你的另一个好建议。这个也是基于自定义操作符的。
0.9 |> should equal (1.0 +/- 0.5)
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)