函数返回动态类型

时间:2015-05-19 20:19:01

标签: scala

所以这是我之前提出的问题: Scala: Function returning an unknown type

这是对此的一次跟进。

之前我问了一个关于添加数字类型并返回更精确的数字类型的问题。通过使用弱一致性规则的类型类并在那里指定类型来解决这个问题。例如,WeakConformance [Int,Double]指定将返回double。

然而,当增加边界的复杂性时,这会带来问题。让我们说我想创建一个类型类来添加两个字节:

class ByteisAddable extends Addable[Byte, Byte] {
  def add(x: Byte, y: Byte): ? = {
    if(Byte.MaxValue - x < y)
      // this is an int
      x + y
    else
      // this is a byte
      (x + y).toByte
  }
}

类型类WeakConformance [Byte,Byte]不能只指定一种类型,因为它可以是Int或Byte。也就是说,在指定要返回的类型之前,必须进行添加值的计算。例如,两个字节:10 + 10应该返回一个值为20的字节。但是两个字节:100 + 100应该返回一个int,否则它将溢出Byte.MaxValue。

还有更好的方法吗?或者有没有办法在计算后指定一个类型?

1 个答案:

答案 0 :(得分:4)

你要求的是一种Dependent Type System。只有少数语言支持这种类型的系统,它是一个活跃的研究领域。

您可以使用子类型从方法返回动态类型:

def add(x: Byte, y: Byte): java.lang.Number = {
  if(Byte.MaxValue - x < y)
    new java.lang.Integer(x + y)
  else
    new java.lang.Byte(x + y)
}

但是,我假设这不是你想要的。我假设您希望动态决定静态返回类型。

这正是问题所在:根据程序的运行时值,您不能拥有静态类型。因此,为了保证add(Byte, Byte)返回另一个Byte(没有溢出),您需要在类型系统中编码某种判断,说明类型的总和不会溢出。你需要依赖类型。依赖类型的虚拟示例是Byte[x < 30],意味着Byte小于30(符号完全是任意的)。

因此,除非你想在Scala中实现你自己的依赖类型系统(这显然超出了SO答案的范围),我很遗憾地告诉你,你运气不好。

看一下this post,了解您正在使用哪种术语:)