下一次测试失败.我直接将GetType调用到函数定义,然后我也在内联函数中调用GetType.生成的类型不相等.
namespace PocTests
open FsUnit
open NUnit.Framework
module Helpers =
let balance ing gas = ing - gas
[<TestFixture>]
type ``Reflected types`` ()=
[<Test>] member x.
``test type equality with inline use`` () =
let inline (=>) f = f.GetType().FullName, f in
let fullName, fval = (=>) Helpers.balance in
Helpers.balance.GetType().FullName |> should equal (fullName)
Run Code Online (Sandbox Code Playgroud)
我怎么能得到相同的类型才能"可比".
当您将函数用作值时,F#不会保证两个创建的对象将是"相同的".在封面下,编译器为每个实例创建一个新的闭包对象,因此false即使你尝试这样的事情,你也会得到结果:
balance.GetType().FullName = balance.GetType().FullName
Run Code Online (Sandbox Code Playgroud)
这是预期的行为 - 当您尝试直接比较函数时,编译器将告诉您函数不满足等式约束并且无法进行比较:
> let balance ing gas = ing - gas;;
val balance : ing:int -> gas:int -> int
> balance = balance;;
error FS0001: The type '(int -> int -> int)' does not support the
'equality' constraint because it is a function type
Run Code Online (Sandbox Code Playgroud)
这意味着您问题的最佳答案是您无法完成的要求.我认为比较函数值很可能不是一个好主意,但如果您提供更多详细信息,为什么要这样做,也许对您的特定问题有更好的答案.
如果您真的想对函数值执行相等测试,那么最简洁的方法可能是定义接口并测试普通对象的相等性:
type IFunction =
abstract Invoke : int * int -> int
let wrap f =
{ new IFunction with
member x.Invoke(a, b) = f a b }
Run Code Online (Sandbox Code Playgroud)
现在,您可以将该balance函数包装在可以比较的接口实现中:
let balance ing gas = ing - gas
let f1 = wrap balance
let f2 = f1
let f3 = wrap balance
f1 = f2 // These two are the same object and are equal
f1 = f3 // These two are different instances and are not equal
Run Code Online (Sandbox Code Playgroud)