我在O
输出类型的类型推断不正确的情况下挣扎了很长时间。为什么scalac会看到Int
而不是(Int,String)
? :
trait Request[I,+O,C[_]]
case class Get[I, O, C[_]](storeName: String, arg: C[I]) extends Request[I,(I,O),C]
object Question {
val get: Request[Int,(Int,String), List] = Get("play", List(1))
}
[error] found : com.viagraphs.idb.Get[Int,Int,List]
[error] required: com.viagraphs.idb.Request[Int,(Int, String),List]
[error] val get: Request[Int,(Int,String), List] = Get("play", List(1))
请忽略W,R,ValidKey
类型类,我猜这些类别无关紧要。
这种方式恰好相同:
case class Append[I : W, O : R : ValidKey](storeName: String, arg: List[I]) extends Request[I,(O,I),List]
object Question {
val get: Request[Int,(Int,String), List] = Get("play", List(1))
}
val append: Request[String,(Int,String), List] = Append("play", List("foo"))
[error] found : com.viagraphs.idb.Append[String,String]
[error] required: com.viagraphs.idb.Request[String,(Int, String),List]
[error] val append: Request[String,(Int,String), List] = Append("play", List("foo"))
我尝试使用-Ytyper-debug
处理这个问题,但它确实很难核心,我不了解它的机制。
更新:我使用Ordering类型类重现它,知道什么是隐式解析规则不满足吗?
trait Req[I,O]
case class Insert[I : Ordering, O : Ordering](arg: I) extends Req[I,O]
def execute[I,O](req: Req[I,O]): O = null.asInstanceOf[O]
def main() = {
val result: Int = execute(Insert("test"))
}
error: type mismatch;
found : String
required: Int
val result: Int = execute(Insert("test"))
答案 0 :(得分:1)
好吧,我试图整理一个简单的例子,它在我的机器上编译得很好,在scala 2.11.4上使用sbt 0.13.7
package example
object Main extends App {
trait Request[I,+O,C[_]]
trait W[A]
trait R[A]
trait ValidKey[A]
implicit val wString = new W[String]{}
implicit val rInt = new R[Int]{}
implicit val validKeyInt = new ValidKey[Int]{}
case class Append[I: W, O: R : ValidKey](storeName: String, arg: List[I]) extends Request[I,(O,I),List]
val append: Request[String,(Int,String), List] = Append("play", List("foo"))
}
我错过了什么吗?
答案 1 :(得分:0)
尝试将其更改为:
Get[Int, String, List]("play", List(1))
我能够在Intellij中重现你的问题,虽然它有一个不同的类型推断问题,但这似乎会让错误消失。