5

在 f# 中,我正在寻找更简洁的等价物:

myNumber >= 2 && myNumber <= 4

我想像

myNumber >=< (2, 4)

有这样的操作吗?

4

3 回答 3

12

没有本地运算符,但您可以定义自己的运算符。

let inline (>=<) a (b,c) = a >= b && a<= c
于 2013-07-29T03:12:54.627 回答
9

约翰的回答正是您所要求的,也是最实用的解决方案。但这让我想知道是否可以定义运算符以启用更接近正常数学符号的语法,即a <= b <= c.

这是一个这样的解决方案:

let inline (<=.) left middle = (left <= middle, middle)
let inline (.<=) (leftResult, middle) right = leftResult && (middle <= right)
let inline (.<=.) middleLeft middleRight = (middleLeft .<= middleRight, middleRight)

1 <=. 3 .<=. 5 .<= 9  // true
1 <=. 10 .<= 5   // false

对此有几点评论:

  • 我用.字符来表示表达式的“中间”
  • .是一个非常慎重的选择,并且不容易更改为您更喜欢的其他角色(例如,如果您可能更喜欢更好的外观1 <=@ 3 @<= 5)。 F# 编译器根据运算符符号的第一个字符更改运算符的关联性和/或优先级。我们想要标准的从左到右的评估/短路,并.启用它。
  • 3 位数的比较完全被优化掉了,但是 4 位数以上的比较会导致 IL 分配元组并执行并非严格必要的各种其他业务:

生成的 IL

于 2013-07-30T01:25:13.513 回答
3

有这样的操作吗?

好问题!答案是“不”,没有,但我希望有。

拉特金的回答很好,但它不会短路评估。因此,如果第一个测试失败,其余子表达式仍然会被评估,即使它们的结果是不相关的。

FWIW,在 Mathematica 中你可以1<x<2像数学一样做。

于 2013-08-01T20:50:02.127 回答