Generics 实施数字
我对Scala还是个新手。我想写几个数学对象(复数、多项式等),它们在一些运算(+、-、*)下是闭合的,这样它们可以用于泛型,也可以使用隐式转换 我似乎已经解决了第一个问题Generics 实施数字,generics,scala,Generics,Scala,我对Scala还是个新手。我想写几个数学对象(复数、多项式等),它们在一些运算(+、-、*)下是闭合的,这样它们可以用于泛型,也可以使用隐式转换 我似乎已经解决了第一个问题 trait GroupUnderAddition[T] { def + (t : T) : T } case class Real(d : Double) extends GroupUnderAddition[Real] { def + (r : Real) = Real(d + r.d) } case clas
trait GroupUnderAddition[T] {
def + (t : T) : T
}
case class Real(d : Double) extends GroupUnderAddition[Real] {
def + (r : Real) = Real(d + r.d)
}
case class Complex(re : Double, im : Double) extends GroupUnderAddition[Complex] {
def + (c : Complex) = Complex(re + c.re, im + c.im)
}
object Test {
implicit def real_to_complex(r : Real) = Complex(r.d, 0)
def test[G <: GroupUnderAddition[G]](a : G, b : G) = a + b
def main(args : Array[String]) {
println(test(Real(5), Real(2)))
}
}
返回复数(7,1)?主要思想是所有GroupUnderAddition都不兼容,因此您似乎想要使用复数代数,我建议构建一个包含GoupUnderAddition的超类。但是,不建议将其设置为案例类(如果您有扩展
案例类的案例类
,请参阅警告)
问题是参数转换不考虑隐式def
,除非指定方法定义
因此,如果您有类似于Real(5).foo
的内容,并且foo
仅为复杂定义,那么隐式def
将适用于此
如果您有这样一个方法:def foo(c:Complex)=……
,那么您可以不使用foo(Real(5))
来调用它
如果要应用隐式转换,必须指定可以转换其参数的方法。对于上述foo
方法,您可以这样做:
def foo[T](c : T)(implicit ct : T => Complex) = ...`
def test[G <: GroupUnderAddition[G],T](a : T, b : G)(implicit ag: T => G) = a + b
def test[G <: GroupUnderAddition[G],T1, T2](a : T1, b : T2)(implicit ag: T1 => G, bg: T2 => G) = a + b
然后可以调用foo(Real(5))
并使用转换
根据您的具体问题,您可以编写如下测试方法:
def foo[T](c : T)(implicit ct : T => Complex) = ...`
def test[G <: GroupUnderAddition[G],T](a : T, b : G)(implicit ag: T => G) = a + b
def test[G <: GroupUnderAddition[G],T1, T2](a : T1, b : T2)(implicit ag: T1 => G, bg: T2 => G) = a + b
不幸的是,当调用上述方法时,编译器不知何故为G
派生了Any
。我现在不知道该如何解决这个问题,我发布了这个答案,希望其他人能填补这个谜题的最后一部分
根据上述最终定义,在指定完整类型时,您至少可以以任何一种方式调用该方法:
println(test[Complex,Real,Complex](Real(5), Complex(2, 1)))
println(test[Complex,Complex,Real](Complex(2,1), Real(5)))
这里真正的问题是,根据您所写的内容,您正在(错误地)假设测试(real(5),Complex(2,1))
在任何方面都是定义良好的。考虑以下事项:
case class Word(s : String) extends GroupUnderAddition[Word] {
def +(w : Word) = Word(s + w.s)
}
这完全满足了您对“GroupUnderAddition”的定义,但尝试在一个真实的(2)中添加一个单词(“Hello”)是没有意义的。结果如何
您试图编码的是一个更大域内的特定加法运算符-它似乎是C上多项式的域-并指定该域的某些子群在加法运算符下闭合。ChrisJamesC的方法可以很高兴地扩展到多项式环,它将捕获您想要的东西。我当然可以这样做,但我想保留泛型。按照你的方式做,如果我想用两个多项式调用test,我需要重写整个过程。是的,但是你有两个不同的问题,第一个问题是你想创建genericGroupUnderAddition
,它将实现方法+
。另一方面,您希望在加法下有一个特定的组
实现两种不同类型的数字:实数
和复数
。这就是为什么你要考虑隐式def,但在你的例子中,我没有找到一个解决方案。考虑到我有一个隐式实数=>复杂函数,test(Real(5),Complex(2,1))定义得很好。我不想让这件事发生在两个孩子身上。