Scala,Imaginary的简单符号(数字)

时间:2013-06-29 15:45:14

标签: scala numbers notation

想象一下,我在Scala中有类Imaginary(x)和类Real(y)。有没有办法做ComplexNumber = 3 + 2i而不是做ComplexNumber = Real(3)+ Imaginary(2)?

感谢。

4 个答案:

答案 0 :(得分:4)

3 + 2.i是否足够?

sealed trait ComplexNumber {
  val re: Int
  val im: Int
}

case class Real(re: Int) extends ComplexNumber { val im: Int = 0 }
implicit class ToReal(val re: Int) extends AnyVal {
  def +(that: Imaginary) = Mixed(re, that.im)
}

case class Imaginary(im: Int) extends ComplexNumber { val re: Int = 0 }
implicit class ToImaginary(val im: Int) extends AnyVal {
  def i: Imaginary = Imaginary(im)
}

case class Mixed(re: Int, im: Int) extends ComplexNumber

用法:

scala> 3 + 2.i
res3: Mixed = Mixed(3,2)

答案 1 :(得分:3)

2i表示2*i。您无法在scala中将2*a替换为2a,因此您应该使用运算符*

case class ComplexNumber(re: Int, im: Int){
  def +(that: ComplexNumber) = ComplexNumber(re + that.re, im + that.im)
  def -(that: ComplexNumber) = ComplexNumber(re - that.re, im - that.im)
  def *(that: ComplexNumber) = ComplexNumber(re*that.re - im*that.im, re*that.im + im*that.re)
}
implicit def intToComplec(i: Int): ComplexNumber = ComplexNumber(i, 0)
object I extends ComplexNumber(0, 1)

用法:

scala> 3 + 2*I
res0: ComplexNumber = ComplexNumber(3,2)

scala> 4 - I
res1: ComplexNumber = ComplexNumber(4,-1)

答案 2 :(得分:2)

小心点。请记住,复数的实部和虚部必须都是真实的。你能做点什么:

case class Complex(real: Real, imag: Real) {
  // in here define all your arithmetic ops
}

然后你可以使用senia的隐式技巧将数字自动转换为实数,并在i中声明一个Real方法,将其转换为虚数。

// inside Real
def i: Complex = Complex(Real(0), this)

我只是提醒你不要过多地复杂代码,只是为了可爱的语法。 Complex(a, b)很好很清楚。如果你想创建一个解析器,请随意,但我会为String值保留,并让代码成为代码。

答案 3 :(得分:1)

不,这是不可能的。编译器的词法分析阶段“拥有”数字字符串的后缀,例如fFloat),dDouble)和l({{ 1}})并且这种表示法没有可扩展性。

您可能想要考虑使用新的字符串插值机制来注释常量。您必须接受解析它们和“标志”,如果您愿意(您的Long),则必须在前缀位置使用。这会给你这样的东西:

i

我不了解新编译器中宏的功能,但也许您可以在编译时完成解析,这样就无法在运行时尝试处理格式错误的值。

这种方法(无论是编译时还是运行时解析)都是灵活的(只要您可以按照您所接受的格式进行调整),但它显然与人们在数学文本中使用的符号不符。