gpt4 book ai didi

基于 Scala 约束的类型和文字

转载 作者:行者123 更新时间:2023-12-04 15:33:40 26 4
gpt4 key购买 nike

我在想是否可以在 Scala 中定义像 NegativeNumber 这样的类型.这种类型将表示一个负数,它会被编译器检查,类似于 Ints、Strings 等。

val x: NegativeNumber = -34
val y: NegativeNumber = 34 // should not compile

同样地:
val s: ContainsHello = "hello world"
val s: ContainsHello = "foo bar" // this should not compile either

我可以像使用其他类型一样使用这些类型,例如:
def myFunc(x: ContainsHello): Unit = println(s"$x contains hello")

这些受约束的类型可以由临时类型(Int、String)支持。

是否可以实现这些类型(也许使用宏)?

自定义文字怎么样?
val neg = -34n  //neg is of type NegativeNumber because of the suffix
val pos = 34n // compile error

最佳答案

不幸的是,这不是您可以在编译时轻松检查的内容。好吧 - 至少如果你不限制对你的类型的操作的话。如果您的目标只是检查数字文字是否为非零,您可以轻松编写一个检查此属性的宏。但是,我认为证明否定文字确实是否定的没有任何好处。

问题不是 Scala 的限制——它有一个非常强大的类型系统——而是事实(在一个相当复杂的程序中)你不能静态地知道每个可能的状态。但是,您可以尝试过度逼近所有可能状态的集合。

让我们考虑引入类型 NegativeNumber 的例子只代表负数。为简单起见,我们只定义一个操作:plus .

假设您只允许添加多个 NegativeNumber ,那么,可以使用类型系统来保证每个 NegativeNumber确实是负数。但这似乎真的很严格,所以一个有用的例子肯定会让我们至少添加一个 NegativeNumber和一般Int .

如果你有一个表达式怎么办 val z: NegativeNumber = plus(x, y)您不知道 x 的值的地方和 y静态(也许它们由函数返回)。你怎么知道(静态地)z indead 是负数吗?

解决该问题的一种方法是引入 Abstract Interpretation 它必须在程序的表示上运行(源代码、抽象语法树等)。

例如,您可以定义一个 格子在具有以下元素的数字上:

  • Top :所有号码
  • + : 所有正数
  • 0 :号码0
  • - : 所有负数
  • Bottom : 不是数字 - 只介绍了每对元素都有一个最大的下限

  • 与订购 Top > ( + , 0 , - ) > Bottom .

    Sign-Lattice

    然后你需要为你的操作定义语义。取交换法 plus从我们的例子:
  • plus(Bottom, something)总是 Bottom ,因为您无法使用无效数字进行计算
  • plus(Top, x) , x != Bottom总是 Top ,因为任意数加上任意数总是任意数
  • plus(+, +)+ ,因为将两个正数相加总是会产生一个正数
  • plus(-, -)- ,因为两个负数相加总会产生负数
  • plus(0, x) , x != Bottomx , 因为 0是加法的身份。

  • 问题是
  • plus - +将是 Top ,因为你不知道它是正数还是负数。

  • 因此,为了静态安全,您必须使用 保守 接近并禁止此类操作。

    more sophisticated numerical domains但最终,它们都遇到了同样的问题:它们代表了对实际程序状态的过度近似。

    我会说这个问题类似于整数溢出/下溢:通常,您不知道一个操作是否会出现溢出 - 您只在运行时知道这一点。

    关于基于 Scala 约束的类型和文字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27278019/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com