是否有一些惯用的scala类型将浮点值限制为由上限和下限定义的给定浮点范围?
具体我希望有一个浮点类型,只允许值介于0.0和1.0之间.
更具体的是我要写一个函数,它接受一个Int和另一个函数,在伪scala中将这个Int映射到介于0.0和1.0之间的范围:
def foo(x : Int, f : (Int => {0.0,...,1.0})) {
// ....
}
Run Code Online (Sandbox Code Playgroud)
已经搜查过电路板,但没有找到合适的.一些隐式魔法或自定义typedef也适合我.
我不知道如何静态地执行它,除了依赖类型(示例),Scala没有.如果你只处理常量,应该可以使用宏或执行必要检查的编译器插件,但如果你有任意浮点型表达式,你很可能必须求助于运行时检查.
这是一种方法.定义执行运行时检查的类,以确保浮点值在所需范围内:
abstract class AbstractRangedFloat(lb: Float, ub: Float) {
require (lb <= value && value <= ub, s"Requires $lb <= $value <= $ub to hold")
def value: Float
}
Run Code Online (Sandbox Code Playgroud)
您可以按如下方式使用它:
case class NormalisedFloat(val value: Float)
extends AbstractRangedFloat(0.0f, 1.0f)
NormalisedFloat(0.99f)
NormalisedFloat(-0.1f) // Exception
Run Code Online (Sandbox Code Playgroud)
或者:
case class RangedFloat(val lb: Float, val ub: Float)(val value: Float)
extends AbstractRangedFloat(lb, ub)
val RF = RangedFloat(-0.1f, 0.1f) _
RF(0.0f)
RF(0.2f) // Exception
Run Code Online (Sandbox Code Playgroud)
如果可以使用值类来获得一些性能会很好,但是requires
在构造函数(当前)中的调用禁止这样做.
编辑:解决@paradigmatic的评论
这是一个直观的论证,为什么依赖于自然数的类型可以在不完全支持依赖类型的类型系统中编码,但是范围浮点数可能不能:自然数是一个可枚举集,这使得对每个元素进行编码成为可能作为路径依赖类型使用Peano数字.然而,实数不再是可枚举的,因此不再可能系统地创建对应于实数的每个元素的类型.
现在,计算机浮点数和实数最终都是有限集,但仍然可以在类型系统中合理有效地枚举.设置计算机自然数当然也非常大,因此造成了在算术编码类型皮亚诺数字问题,请参阅最后一段文章.但是,我声称通常使用前n个(对于一个相当小的n)自然数就足够了,例如,由HLists证明.对浮点数做出相应的声明是不太令人信服的 - 编辑10,000浮点数在0.0和1.0之间,或者更确切地说10,000在0.0和100.0之间编码会更好吗?
归档时间: |
|
查看次数: |
1368 次 |
最近记录: |