首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FsUnit与浮点数的等价性检验

FsUnit与浮点数的等价性检验
EN

Stack Overflow用户
提问于 2010-07-08 23:48:37
回答 2查看 687关注 0票数 3

我开始使用FsUnit来测试F#代码。它使得以F#风格表达断言成为可能,例如:

代码语言:javascript
复制
[<Test>]
member this.``Portugal voted for 23 countries in 2001 Eurovision contest``() =
    this.totalVotes 
    |> getYearVotesFromCountry "Portugal" 2001
    |> Seq.length
    |> should equal 23

注意我从FsUnit得到的“应该等于23”。下面是FsUnit对它的定义:

设x=新的EqualConstraint(x)

对于浮点数,事情就没那么简单了。我必须在方法内使用EqualConstraint。它自然适合C#:

代码语言:javascript
复制
Assert.That(result).Is.EqualTo(1).Within(0.05);

当然,我希望能够用F#编写代码:

代码语言:javascript
复制
result |> should equal 1 within 0.05

但这并不管用。我最终定义了一个新函数:

代码语言:javascript
复制
let almostEqual x = (new EqualConstraint(x)).Within(0.01)

或者,如果我想将精度参数化,我可以将其指定为第二个参数:

代码语言:javascript
复制
let equalWithin x y = (new EqualConstraint(x)).Within(y)

但是没有一个是漂亮的。我想以一种更自然的方式为F#定义“内部”函数,这样它就可以和equal一起使用。F#不支持方法重载,所以看起来我不能这样定义它,这样"equal“既可以单独使用,也可以与”with“一起使用。

有什么想法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-07-09 00:27:09

这是一个有趣的问题!我不认为您可以以任何方式将within 0.05附加到现有的should equal定义中。为此,您需要向should函数添加参数,但这需要在库中具有固定数量的参数。

用F#优雅地编写它的一种方法是创建自定义运算符+/-。请注意,您仍然需要使用括号,但它看起来非常整洁:

代码语言:javascript
复制
0.9 |> should equal (1.0 +/- 0.5)

运算符只是构造需要在equal函数中显式处理的特殊类型的值。具体实现如下:

代码语言:javascript
复制
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)
票数 12
EN

Stack Overflow用户

发布于 2010-07-09 00:20:31

术语说明: F#确实支持方法重载;它不支持重载let绑定函数(模块中定义的“自由”函数)。

例如,您可以将其设置为带点的should.equal,这样equal就是should对象上的一个方法,您可以重载该方法。尽管这仍然没有帮助,因为您不能重载curried参数。嗯。

好吧,我没有太多的帮助可以提供。就我个人而言,我不喜欢库中的这些语法糖。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3205453

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档