Scala type checker cannot infer types correctly
I simplified a problem that I had with Scala type inference:
  case class HalfEdg[N,E](e:E, n:N)
  case class Nod[N,E](head:N, edgs:HalfEdg[N,E])
  case class AA[E](e:E) {
    def ->[N](n:N):HalfEdg[N,E] = HalfEdg(e,n)
  }
  def --[E](e:E):AA[E] = AA(e)
And I can make this variable:
val x = Nod[Int,String](13, --("aa")->(12))
And then I want to extend it to following types:
  case class Foo[N](e:N => Boolean)
  case class Bar[E](e:E => Boolean)
  case class BB[E](e:Bar[E]) {
    def ->[N](n:Foo[N]):HalfEdg[Foo[N],Bar[E]] = HalfEdg(e,n)
  }  
  def --?[E](e:E => Boolean):BB[E] = BB(Bar(e))
But this time I cannot do the same thing because compiler cannot infer the type of function inside Foo and Bar: (I can statically type them and will compile)
  val x1 = Nod[Foo[Int],Bar[String]](Foo(x => x == 10), --?(x => x == "")->(Foo(z => z == 10)))
How can I solve this problem?
 The type-inference failure is centered around the fact that the compiler can't figure out that the type N in Foo(z => z == 10) is the same N as the type N from the earlier Foo(x => x == 10) .  One possible route around this is to ensure that the definitions of Foo , Bar , BB , and --?  are all using the same N and E .  This might be done by wrapping them in a parent ("context") trait parameterised with the types N and E .  Eg:  
trait Baz[N,E] {
  case class Foo(e:N => Boolean)
  case class Bar(e:E => Boolean)
  case class BB(e:Bar) {
    def ->(n:Foo):HalfEdg[Foo,Bar] = HalfEdg(e,n)
  }
  def --?(e:E => Boolean):BB = BB(Bar(e))
}
 From here, you could perform the operations you need within a specific context, being a version of Baz with the particular desired types for N and E satisfied:  
object IntStrBaz extends Baz[Int,String] {
  // do your work in here
  val x1 = Nod[Foo,Bar](Foo(x => x == 10), --?(x => x == "")->(Foo(z => z == 10)))
}
Pasting into the REPL, we no longer get type inference complaints:
scala> IntStrBaz.x1
res0: Nod[IntStrBaz.Foo,IntStrBaz.Bar] = Nod(Foo(<function1>),HalfEdg(Bar(<funct
ion1>),Foo(<function1>)))
All you need is to simplify your expression and it will easily shows your errors. You've missed two places to set type:
  val bbE = --?[String](x => x == "")
  val foo = Foo(z => z == 10)
  val zz = bbE->(foo)
  val x1 = Nod[Foo[Int],Bar[String]](Foo(x => x == 10), zz)
For such kind of problems it's much easier to identify the problem if you help compiler with type inference.
链接地址: http://www.djcxy.com/p/38024.html上一篇: 关于scala类型推断的编译错误
下一篇: Scala类型检查器无法正确推断类型
