此解决方案准确生成所需的语法。令我惊讶的是,速度相当快。此外,这似乎是使用单子的一个很好的例子,也称为计算表达式。
// Generic
let inline mOp1<'a> op sample x = op sample x, sample
let inline mOp2<'a> op1 op2 (b, sample) x = op1 b (op2 sample x), sample
// Implementation for (=) and (&&)
let (==) = mOp1 (=)
let (&=) = mOp2 (&&) (=)
// Use
let ret1 = a == b &= c &= d &= e |> fst
这个怎么运作
该方法是一个非常简化的State monad。monadic 类型是 的元组(bool, 'T)
。第一个组件是正在进行的计算的布尔值,第二个是要比较的样本值。
(==)
将初始化 monad,类似于Delay
运算符。
(&=)
用于所有后续比较。它类似于Bind
运算符。
我们不需要Return
,因为fst
会很好用。
mOp1
并且mOp2
是对逻辑操作的抽象。这些允许定义您自己的运算符。以下是or-equal
和的示例and-greater-than
:
let (|=) = mOp2 (||) (=)
let (.>) = mOp1 (>)
let (&>) = mOp2 (&&) (>)
// Use
let ret2 = a == b |= c |= d |= e |> fst // if any of b,c,d,e equals to a
let ret3 = 5 .> 3 &> 4 |> fst // true: 5>3 && 5>4
let ret4 = 5 .> 3 &> 8 &> 4 |> fst // false
表现
我真的很喜欢@ildjarn 的漂亮解决方案,但是构建List
速度很慢,所以我的主要目标是性能。
运行 8 次比较链,1000 万次:
- 04972ms
a=b && a=с && ...
List
基于23138ms
- 12367ms 一元