Scala数值范围但不是集合

时间:2014-03-23 17:08:57

标签: scala

Scala中的数字范围是否不是集合?也就是说,不是为了迭代,而是像#34;这样的东西是这个范围内的数字?"或"这些范围是否重叠?"我只能想出下面的例子,但显然它很慢:

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

当然可以创建我自己的类,但看起来很常见,我觉得Scala中已经有了一些东西。

1 个答案:

答案 0 :(得分:4)

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某个内部状态反映了开放端点和封闭端点之间的差异,那么你就会遇到只有{{1}的一次隐式转换的问题。 } Tupel2[Double, Double]可以在范围内,因此您无法控制创建开放和封闭端点的任何其他三种组合。实际上,现在我想到它,Spire如何表示间隔并不重要,除非隐式转换的输入带有关于要创建什么样的间隔的信息,问题成立。我想,您可以向元组添加更多插槽以进行端点打开/关闭区分。再次,你在简洁中失去了一些,并且它永远不会像使用数学文本的符号那样优雅。

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

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

Interval[Double]

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

相关问题