隐式类和“不是类型参数的成员”错误

时间:2018-08-29 08:08:24

标签: scala typeclass implicit-class

我有以下类型类定义-

trait ToBigInt[A] {
  def toBigInt(n: A): BigInt
}

object ToBigInt {
  def apply[A](implicit t: ToBigInt[A]): ToBigInt[A] = t

  implicit val toBigIntByte: ToBigInt[Byte] = (x: Byte) => BigInt(x)

  implicit val toBigIntShort: ToBigInt[Short] = (x: Short) => BigInt(x)

  implicit val toBigIntInt: ToBigInt[Int] = (x: Int) => BigInt(x)

  implicit val toBigIntLong: ToBigInt[Long] = (x: Long) => BigInt(x)

  implicit val toBigIntBigInt: ToBigInt[BigInt] = identity _

  implicit class RichToBigInt[A: ToBigInt](value: A) {
    def toBigInt: BigInt = ToBigInt[A].toBigInt(value)
  }
}

值得注意的是,在ToBigInt对象中,我包括一个包含toBigInt方法的隐式类。

不幸的是,以下代码无法编译-

import FromBigInt._
import ToBigInt._

final class Unsigned[A: BoundedIntegral] private (val value: A) {
  def toBigInt: BigInt =
    BoundedIntegral[A].toBigInt(value) - BoundedIntegral[A].toBigInt(BoundedIntegral[A].minValue)

  override def toString: String = toBigInt.toString

  override def equals(that: Any): Boolean = that match {
    case unsigned: Unsigned[A] => toBigInt == unsigned.toBigInt
    case _ => false
  }
}

object Unsigned {
  def apply[A: BoundedIntegral, N: ToBigInt](n: N): Unsigned[A] = {
    assert(n.toBigInt >= BigInt(0), "Integer cannot be negative")
    assert(n.toBigInt <= BoundedIntegral[A].maxValue.toBigInt * 2 + 1, "Integer out of range")
    new Unsigned[A]((n.toBigInt - BoundedIntegral[A].minValue.toBigInt).fromBigInt)
  }
}

trait BoundedIntegral[A] extends Bounded[A] with ToFromBigInt[A]

object BoundedIntegral {
  def apply[A](implicit b: BoundedIntegral[A]): BoundedIntegral[A] = b
}

[error] Unsigned.scala:24:14: value toBigInt is not a member of type parameter N
[error]     assert(n.toBigInt >= BigInt(0), "Integer cannot be negative")
[error]              ^
[error] Unsigned.scala:25:14: value toBigInt is not a member of type parameter N
[error]     assert(n.toBigInt <= BoundedIntegral[A].maxValue.toBigInt * 2 + 1, "Integer out of range")
[error]              ^
[error] Unsigned.scala:25:54: value toBigInt is not a member of type parameter A
[error]     assert(n.toBigInt <= BoundedIntegral[A].maxValue.toBigInt * 2 + 1, "Integer out of range")
[error]                                                      ^
[error] Unsigned.scala:26:24: value toBigInt is not a member of type parameter N
[error]     new Unsigned[A]((n.toBigInt - BoundedIntegral[A].minValue.toBigInt).fromBigInt)
[error]                        ^
[error] Unsigned.scala:26:63: value toBigInt is not a member of type parameter A
[error]     new Unsigned[A]((n.toBigInt - BoundedIntegral[A].minValue.toBigInt).fromBigInt)

另一方面,intellij的代码没有问题。此代码有什么问题?

更新:我已经缩小了范围-

package unsigned

trait ToBigInt[A] {
  def toBigInt(n: A): BigInt
}

object ToBigInt {
  def apply[A](implicit t: ToBigInt[A]): ToBigInt[A] = t

  implicit class RichToBigInt[A: ToBigInt](value: A) {
    def toBigInt: BigInt = ToBigInt[A].toBigInt(value)
  }

  def test1[A: ToBigInt](n: A): BigInt = n.toBigInt
}

trait FromBigInt[A] {
  def fromBigInt(n: BigInt): A
}

object FromBigInt {
  def apply[A](implicit t: FromBigInt[A]): FromBigInt[A] = t

  implicit class RichToBigInt(value: BigInt) {
    def fromBigInt[A: FromBigInt]: A = FromBigInt[A].fromBigInt(value)
  }
}

object Test1 {
  import ToBigInt._
  def test1[A: ToBigInt](n: A): BigInt = n.toBigInt
}

object Test2 {
  import ToBigInt._
  import FromBigInt._
  def test2[A: ToBigInt](n: A): BigInt = n.toBigInt
}

import FromBigInt._对象中未使用的导入Test2导致编译时错误。

 ....:37:44: value toBigInt is not a member of type parameter A
[error]   def test2[A: ToBigInt](n: A): BigInt = n.toBigInt
[error]                                            ^
[error] one error found

1 个答案:

答案 0 :(得分:0)

我不认为您使用的是隐式的方式。

apply中将方法Unsigned声明为def apply[A <: BoundedIntegral[_], N](n: N)(implicit bigInt: ToBigInt[N])似乎可以解决编译的这一部分