scala Stack Overflow in implicit object 未应用
scala StackOverflow on implicit object unapply
我正在编写一个类型类来在类型之间进行转换,我注意到隐式对象上的 unapply 方法有些不寻常。具体
object IntString extends PartialFunction[String, Int] {
def isDefinedAt(x: String) = Try(x.toInt).isSuccess
def apply(v1: String) = v1.toInt
def unapply(a:String):Option[Int] = if(this.isDefinedAt(a)) Some(this.apply(a)) else None
}
val s = "1000"
val IntString(i) = s
完美运行但是
implicit object IntString extends PartialFunction[String, Int] {
def isDefinedAt(x: String) = Try(x.toInt).isSuccess
def apply(v1: String) = v1.toInt
def unapply(a:String):Option[Int] = if(this.isDefinedAt(a)) Some(this.apply(a)) else None
}
val s = "1000"
val IntString(i) = s
在apply
方法中给出了一个Whosebug。我希望能够隐含对象,这样我就可以做类似
的事情
def parse[A,B](a:A)(implicit ev:PartialFunction[A,B]) = ev(a)
除了显式 apply/unapply。
apply
都出错了,特别是 v1.toInt
。 java.lang.String
没有 toInt
方法。它由 StringLike
隐式提供。但是 Int
也 有一个 toInt
方法,并且您提供了从 String => Int
.
的隐式转换
编译器发现您想在 String
上调用 toInt
。编译器知道 Int
有一个 toInt
方法,而不是从 StringLike
中选择丰富的方法,而你在范围内提供了一个隐式的 String => Int
,所以它使用那个.但是再次使用您的转换调用 apply
,它会无限重复该过程。
一个简单的解决方案是使用实际类型 class,而不是 PartialFunction
:
trait Conv[A, B] {
def isDefinedAt(x: A): Boolean
def apply(v1: A): B
def unapply(a: A): Option[B]
}
implicit object IntString extends Conv[String, Int] {
def isDefinedAt(x: String) = Try(x.toInt).isSuccess
def apply(v1: String): Int = v1.toInt
def unapply(a: String): Option[Int] =
if(this.isDefinedAt(a)) Some(this.apply(a)) else None
}
scala> val IntString(i) = s
i: Int = 1000
然后您将 parse
更改为:
def parse[A, B](a: A)(implicit ev: Conv[A,B]) = ev(a)
我正在编写一个类型类来在类型之间进行转换,我注意到隐式对象上的 unapply 方法有些不寻常。具体
object IntString extends PartialFunction[String, Int] {
def isDefinedAt(x: String) = Try(x.toInt).isSuccess
def apply(v1: String) = v1.toInt
def unapply(a:String):Option[Int] = if(this.isDefinedAt(a)) Some(this.apply(a)) else None
}
val s = "1000"
val IntString(i) = s
完美运行但是
implicit object IntString extends PartialFunction[String, Int] {
def isDefinedAt(x: String) = Try(x.toInt).isSuccess
def apply(v1: String) = v1.toInt
def unapply(a:String):Option[Int] = if(this.isDefinedAt(a)) Some(this.apply(a)) else None
}
val s = "1000"
val IntString(i) = s
在apply
方法中给出了一个Whosebug。我希望能够隐含对象,这样我就可以做类似
def parse[A,B](a:A)(implicit ev:PartialFunction[A,B]) = ev(a)
除了显式 apply/unapply。
apply
都出错了,特别是 v1.toInt
。 java.lang.String
没有 toInt
方法。它由 StringLike
隐式提供。但是 Int
也 有一个 toInt
方法,并且您提供了从 String => Int
.
编译器发现您想在 String
上调用 toInt
。编译器知道 Int
有一个 toInt
方法,而不是从 StringLike
中选择丰富的方法,而你在范围内提供了一个隐式的 String => Int
,所以它使用那个.但是再次使用您的转换调用 apply
,它会无限重复该过程。
一个简单的解决方案是使用实际类型 class,而不是 PartialFunction
:
trait Conv[A, B] {
def isDefinedAt(x: A): Boolean
def apply(v1: A): B
def unapply(a: A): Option[B]
}
implicit object IntString extends Conv[String, Int] {
def isDefinedAt(x: String) = Try(x.toInt).isSuccess
def apply(v1: String): Int = v1.toInt
def unapply(a: String): Option[Int] =
if(this.isDefinedAt(a)) Some(this.apply(a)) else None
}
scala> val IntString(i) = s
i: Int = 1000
然后您将 parse
更改为:
def parse[A, B](a: A)(implicit ev: Conv[A,B]) = ev(a)