繁体   English   中英

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

[英]Scala type checker cannot infer types correctly

我简化了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)))

我怎么解决这个问题?

类型推测失败围绕事实为中心,该编译器不能弄清楚该类型NFoo(z => z == 10)相同的 N作为类型N从早期Foo(x => x == 10) 解决此问题的一种可能方法是确保FooBarBB--?的定义--? 都使用相同的NE 这可以通过将它们包装在参数为NE的父(“上下文”)特征中来完成。 例如:

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的版本,满足NE的特定所需类型:

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

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

scala> IntStrBaz.x1
res0: Nod[IntStrBaz.Foo,IntStrBaz.Bar] = Nod(Foo(<function1>),HalfEdg(Bar(<funct
ion1>),Foo(<function1>)))

您所需要做的只是简化您的表达,它会轻松显示您的错误。 您错过了两个设置类型的地方:

  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)

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM