这是一个简化的例子
我有以下代码:
import scala.language.implicitConversions
trait Mapping[I, O]
trait KeyMapping[K, I, O]
implicit def toMapping[I, O](s: I => O): Mapping[I, O] = ???
implicit def toKeyMapping[K, I, O](s: (K, I => O))(
implicit ev: (I => O) => Mapping[I, O]): KeyMapping[K, I, O] = ???
def test[K, I, O, M](s: M)(
implicit ev: M => KeyMapping[K, I, O]
):KeyMapping[K, I, O] = ???
val x = test(1 -> {s:String => true})
^
这会出现以下错误:
type mismatch;
found: ((Int, Nothing => Boolean)) => KeyMapping[Int,Nothing,Boolean]
required: ((Int, String => Boolean)) => KeyMapping[Int,Input,Boolean]
为什么会这样?
这可以解决吗?
答案 0 :(得分:1)
我打算说:
def test[K, I, O](s: (K, I => O))(
implicit ev: ((K, I => O)) => KeyMapping[K, I, O]
):KeyMapping[K, I, O] = ???
没有M,请注意额外的parens。它将自动尝试应用,但不会尝试。
您可以在2.11(2.10中的-Ytyper-debug
)中使用-Yinfer-debug
来查看它推断Nothing
。
函数在输入中是逆变的,因此推断Nothing
意味着它为您的I => O
采用最宽的类型。您可以进行竞争Mapping
次转化,其中一次转换为Nothing
。
答案 1 :(得分:0)
我通过使用隐式转换器而不是隐式转换来解决它。
import scala.language.implicitConversions
trait Mapping[I, O]
trait KeyMapping[K, I, O]
trait MappingConverter[M, I, O] {
def convert(m: M): Mapping[I, O]
}
trait KeyMappingConverter[M, K, I, O] {
def convert(m: M): KeyMapping[K, I, O]
}
implicit def toMapping[I, O] =
new MappingConverter[I => O, I, O] {
def convert(m: I => O): Mapping[I, O] = ???
}
implicit def toKeyMapping[K, I, O, M](
implicit mapping: MappingConverter[M, I, O]) =
new KeyMappingConverter[(K, M), K, I, O] {
def convert(m: (K, M)): KeyMapping[K, I, O] = ???
}
def test[K, I, O, M](s: M)(
implicit converter: KeyMappingConverter[M, K, I, O]): KeyMapping[K, I, O] = ???
val x = test(1 -> { s: String => true })