我在F#做了一个有趣的项目,这是DSL for Camel.Net。
在某些时候,我想查看条件。但程序员输入的条件应该评估为对象树。所以我想要表达" a = b"评估为" SomeType.Equals(a,b)"
在F#中甚至可以吗?
我有这个:
type Macro =
| Header of string
| XPath of string
| Const of string
| Func of (Message -> string)
with
static member (=) (l:Macro, r:Macro) = Equals(l,r)
static member (=) (l:Macro, r:string) = Equals(l,Const(r))
and Comparison =
| Equals of Macro * Macro
现在所有内容都在" Macro"将作为" Macro.Func" - 用" Func&#34 ;;使用" Message"执行函数。作为输入参数并将输出字符串。因此,Equals(a,b)将在运行时评估为字符串比较。
但是这段代码有问题。运算符(=)确实编译(它有一个警告),但它不能按我的意愿使用。
这不能在fsi:
中编译let c1 = Header("property") = "somevalue"
我确实阅读了关于此主题的another question和bit more。
它没有回答我的问题。
[<NoEquality; NoComparison>]
- 完全关闭(=)运算符。
[<CustomEquality; CustomComparison>]
- 希望你实现一个返回bool的(=)运算符。
甚至可以在F#中找到我想要的东西吗?假设我能找到方法,match x with
是否仍然有效?
答案 0 :(得分:2)
当然,出于性能原因,我在System.IEquatable<T>
方面对运营商进行了重新实施:
#nowarn "86" // F# doesn't like it when you do this
[<AutoOpen>]
module FastEquals =
let inline eq<'a when 'a :> System.IEquatable<'a>> (x:'a) (y:'a) = x.Equals y
let inline (=) x y = eq x y
let inline (<>) x y = not (eq x y)
举个例子,你需要适应自己的目的。
答案 1 :(得分:2)
感谢上述Asik的回答,结合重读this post:
这适用于fsi:
KeyError: 'ecoinvent 3_2 CutOff'
请注意,当静态“CompareEquals”方法位于“宏”类型中时,它不起作用。
如果你看一下op_Equals的签名:
type Message = class end
type Macro =
| Header of string
| XPath of string
| Const of string
| Func of (Message -> string)
type Comparison =
| Equals of Macro * Macro
type Operators = Operation with
static member CompareEquals (Operation, l:Macro, r:Macro) = Equals(l,r)
static member CompareEquals (Operation, l:Macro, r:string) = Equals(l,Const(r))
#nowarn "0086" "0064"
let inline (=) (l:'N) (r:'M) = ((^T or ^N or ^M) : (static member CompareEquals : ^T * ^N * ^M -> _) (Operation, l, r))
let c1 = Header("property1") = Header("property2")
let c2 = Header("property") = "somevalue"
这是一个非常奇怪的语法。我不明白“什么时候”之后的部分。这很有效,重要。