所以这是我之前提出的问题: 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。
还有更好的方法吗?或者有没有办法在计算后指定一个类型?
答案 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,了解您正在使用哪种术语:)