我简化了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)))
我该如何解决这个问题?
答案 0 :(得分:0)
类型推断失败的核心是编译器无法确定N
中的Foo(z => z == 10)
类型是相同 {{1来自早期N
的{{1}}类型。围绕此问题的一种可能途径是确保N
,Foo(x => x == 10)
,Foo
和Bar
的定义全部使用相同的BB
和{{1 }}。这可以通过将它们包装在使用类型--?
和N
参数化的父(" context")特征中来完成。例如:
E
从这里开始,您可以在特定的上下文中执行所需的操作,作为N
的版本,其中E
和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))
}
满足特定的所需类型:
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)
对于这类问题,如果您帮助编译器进行类型推断,则更容易识别问题。