Scala类型检查器无法正确推断类型

时间:2015-10-31 19:34:46

标签: scala types

我简化了Scala类型推断的问题:

  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)

我可以制作这个变量:

val x = Nod[Int,String](13, --("aa")->(12))

然后我想将它扩展到以下类型:

  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))

但是这次我不能做同样的事情,因为编译器无法推断出Foo和Bar中的函数类型:(我可以静态地输入它们并将编译)

  val x1 = Nod[Foo[Int],Bar[String]](Foo(x => x == 10), --?(x => x == "")->(Foo(z => z == 10)))

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

类型推断失败的核心是编译器无法确定N中的Foo(z => z == 10)类型是相同 {{1来自早期N的{​​{1}}类型。围绕此问题的一种可能途径是确保NFoo(x => x == 10)FooBar的定义全部使用相同的BB和{{1 }}。这可以通过将它们包装在使用类型--?N参数化的父(" context")特征中来完成。例如:

E

从这里开始,您可以在特定的上下文中执行所需的操作,作为N的版本,其中Etrait 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)) } 满足特定的所需类型:

Baz

粘贴到REPL中,我们不再收到类型推断投诉:

N

答案 1 :(得分:-1)

您只需要简化表达,就可以轻松显示错误。 你错过了两个设置类型的地方:

  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)

对于这类问题,如果您帮助编译器进行类型推断,则更容易识别问题。