我开始使用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注意我从FsUnit得到的“应该等于23”。下面是FsUnit对它的定义:
设x=新的EqualConstraint(x)
对于浮点数,事情就没那么简单了。我必须在方法内使用EqualConstraint。它自然适合C#:
Assert.That(result).Is.EqualTo(1).Within(0.05);当然,我希望能够用F#编写代码:
result |> should equal 1 within 0.05但这并不管用。我最终定义了一个新函数:
let almostEqual x = (new EqualConstraint(x)).Within(0.01)或者,如果我想将精度参数化,我可以将其指定为第二个参数:
let equalWithin x y = (new EqualConstraint(x)).Within(y)但是没有一个是漂亮的。我想以一种更自然的方式为F#定义“内部”函数,这样它就可以和equal一起使用。F#不支持方法重载,所以看起来我不能这样定义它,这样"equal“既可以单独使用,也可以与”with“一起使用。
有什么想法吗?
发布于 2010-07-09 00:27:09
这是一个有趣的问题!我不认为您可以以任何方式将within 0.05附加到现有的should equal定义中。为此,您需要向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)发布于 2010-07-09 00:20:31
术语说明: F#确实支持方法重载;它不支持重载let绑定函数(模块中定义的“自由”函数)。
例如,您可以将其设置为带点的should.equal,这样equal就是should对象上的一个方法,您可以重载该方法。尽管这仍然没有帮助,因为您不能重载curried参数。嗯。
好吧,我没有太多的帮助可以提供。就我个人而言,我不喜欢库中的这些语法糖。
https://stackoverflow.com/questions/3205453
复制相似问题