【问题标题】:Scala - Define types for a number in a rangeScala - 为范围内的数字定义类型
【发布时间】:2017-11-27 05:21:42
【问题描述】:

我想知道是否可以在 Scala 中定义一个类型,该类型将一个数字包装在一个范围内并在编译时断言它的有效性。例如:[0,1] 范围内的所有数字,因此我可以定义一个采用 BetweenZeroAndOne 类型的函数。我知道我可以定义一个包含/包装数字的案例类,然后检查数字是否在运行时范围内,并且我还可以使用隐式转换 Int => BetweenZeroAndOne、Double => BetweenZeroAndOne、BetweenZeroAndOne => Int.. .但是可以定义0到1之间的数字类型吗?

谢谢,

【问题讨论】:

  • 如果您谈论的是:data Bool = False |是的(在 Haskel 中)。那我觉得你不能这样做。
  • @Pavel 我对 haskell 了解不多,但您的定义类似于 OO 中的层次结构,例如 True 扩展 Bool,False 扩展 Bool。我要求的是连续值。
  • 顺便问一下你的范围有多大??
  • @Pavel 从 0 到 1。无限数。
  • 刚刚发布了使用 scala 枚举的可能方法,可能是很好的解决方法等

标签: scala validation types compile-time


【解决方案1】:

使用refined:

scala> type ZeroToOne = Not[Less[W.`0.0`.T]] And Not[Greater[W.`1.0`.T]]
defined type alias ZeroToOne

scala> refineMV[ZeroToOne](1.8)
<console>:40: error: Right predicate of (!(1.8 < 0.0) && !(1.8 > 1.0)) failed:
Predicate (1.8 > 1.0) did not fail.

【讨论】:

    【解决方案2】:

    这是可能的解决方案,希望我正确理解您的问题: 纯粹使用内置 scala 功能:

    object MyInt extends Enumeration {
      type MyInt = Value
      // this is most "fragile" part of this solution
      val Zero, One, Two, Three = Value
    }
    
    object MyIntToIntConverter{
      import MyInt._
      implicit def MyIntToInt(x: MyInt) : Int = x.id
      implicit def IntToMyInt(x: Int) : MyInt = MyInt.apply(x)
    }
    
    import MyInt._
    import MyIntToIntConverter._
    
    val x : Int  = MyInt.Three
    
    val t : MyInt = 3
    

    【讨论】:

    • 这个解决方案只适用于离散范围,不是吗?
    猜你喜欢
    • 1970-01-01
    • 2015-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-24
    • 1970-01-01
    相关资源
    最近更新 更多