【问题标题】:Scala numeric range but not collectionScala数字范围但不是集合
【发布时间】:2014-03-23 17:08:57
【问题描述】:

Scala 中有不是集合的数字范围?也就是说,不是用于迭代,而是用于诸如“这个范围内的数字吗?”之类的事情。或“这些范围是否重叠?”等等。我只能想出下面的例子,但显然它很慢:

(1.0f to 999999.0f by 0.01f).view.contains(123123.12f)

当然可以为此创建我自己的类,但它似乎很常见,以至于我觉得 Scala 中已经有一些东西了。

【问题讨论】:

  • <=< 有什么问题?我不知道标准库中有一个类,但需要四种方法来处理所有情况(包括/不包括 x 下限/上限)。就我个人而言,我从来不知道tountil 之间的区别
  • 我认为使用

标签: scala


【解决方案1】:

Spire 有一个 Interval 类型,可以做你想做的事情。

附录

关于您关于创建Interval 实例的更简洁语法的问题。有几个选项。一种是简单地使用 import 使创建过程不那么冗长:

import Interval.{closed => ci}

val ci1 = ci(1.0, 2.0)

……但这并没有太大的改进。

另一种选择可能是使用从 Tuple2[Double, Doublle]Interval[Double] 的隐式转换:

implicit def t2toI(pair: Tuple2[Doube, Double]): Interval[Double] =
  Interval.closed(pair._1, pair._2)

val ci2: Interval[Double] = (1.0, 2.0)

在这种情况下,必须给出 val 的类型使得这又是一个收益不大的情况。但是,如果您正在调用一个以Interval[Double] 作为参数的方法,则该方法的形式参数的类型注释足以触发隐式转换。

我实际上对 Spire 了解不多,但如果只有一个 Interval 某种内部状态反映了开放端点和封闭端点之间的差异,那么您的问题是只有一个从 Tupel2[Double, Double] 到 @987654331 的隐式转换@ 可以在范围内,因此您无法控制创建其他三种开放和封闭端点组合中的任何一种。实际上,现在我想起来了,Spire 如何表示区间并不重要,除非隐式转换的输入包含有关要创建哪种区间的信息,否则问题就成立了。我想,您可以向元组添加更多插槽以区分端点打开/关闭。再一次,你失去了一些简洁性,它从来没有像使用数学文本的符号那样优雅。

因为括号和方括号都“属于”语言规范,传统的数学符号将永远无法用于经典的内部 DSL。

最后,可能是最好的解决方案,您可以创建一个字符串插值器,使您能够编写如下内容:

val i1 = i"[1.0, $end)"
val i2 = i"($begin, 4.0]'

等等。同样,我还没有任何直接经验,但我相信用于创建新插值器的 API 非常简单。

【讨论】:

  • 这太好了,谢谢!当我们这样做时,我找不到一种方法来创建带有隐式的间隔,也许你知道吗?比Interval.closed(1.0f, 2.0f)短的东西@
猜你喜欢
  • 2020-09-29
  • 2020-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-15
  • 2022-11-18
  • 2011-12-23
  • 1970-01-01
相关资源
最近更新 更多