【发布时间】:2019-02-03 22:52:37
【问题描述】:
我有以下类型类定义-
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
}
Test2 对象中未使用的导入 import FromBigInt._ 导致编译时错误。
....: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
【问题讨论】:
-
嗨!您的示例无法编译,因为 Bounded 未声明。提供代码时请尝试提供 mCve :-)
-
@C4stor 我已经缩小了问题的范围。我将编辑我原来的问题
标签: scala typeclass implicit-class