必须完全知道匿名函数的参数类型.(SLS 8.5)

The*_*ell 31 lambda scala function-literal pattern-matching

我有一个函数文字

{case QualifiedType(preds, ty) =>
               t.ty = ty ;
               Some((emptyEqualityConstraintSet,preds)) }
Run Code Online (Sandbox Code Playgroud)

这会导致错误消息

missing parameter type for expanded function The argument types of an anonymous function
must be fully known. (SLS 8.5) Expected type was:
? => Option[(Typer.this.EqualityConstraintSet, Typer.this.TypeRelationSet)]
Run Code Online (Sandbox Code Playgroud)

我查看了SLS 8.5,但未找到解释.

如果我自己扩展功能

{(qt : QualifiedType) =>
  qt match {case QualifiedType(preds, ty) =>
               t.ty = ty ;
               Some((emptyEqualityConstraintSet,preds)) }}
Run Code Online (Sandbox Code Playgroud)

错误消失了.

(a)为什么这是一个错误?

(b)我该怎么做才能解决这个问题?

我尝试了明显的修复,即: QualifiedType在模式和=>之间添加,但这是一个语法错误.


我注意到的一件事是上下文有所不同.如果我使用函数literal作为声明为期望a的函数的参数QualifiedType => B,则没有错误.但是如果我将它用作期望a的函数的参数A => B,则会出现错误.我希望这里发生的事情是,由于模式可以想象应用于类型为QualifiedType的超类型的对象,编译器不愿意在不保证函数不会应用于的情况下分配明显的类型.任何不是QualifiedType的东西.我真正想要的是能够写出{QualifiedType( preds, ty) => ...} 并让它与Haskell的意思相同\QualifiedType(preds,ty) -> ....

Lui*_*hys 23

{ case X(x) => ... }是一个部分函数,​​但编译器仍然不知道你的输入类型是什么,除了它是一个超类型X.通常这不是问题,因为如果您正在编写匿名函数,则从上下文中可以知道该类型.但是这里是你可以提供的类型:

case class Foo(x: Int)

// via annotation
val f: Foo => Int = { case Foo(x) => x }

// use pattern matching
val f = (_: Foo) match { case Foo(x) => x }

// or more normally, write as a method
def f(a: Foo) = a match { case Foo(x) => x }
def f(a: Foo) = a.x
Run Code Online (Sandbox Code Playgroud)

您可能已经注意到,在这里使用函数文字/模式匹配是毫无意义的.在您的情况下,您似乎只需要一个常规方法:

def whatever(qt: QualifiedType) = {
  t.ty = qt.ty
  Some((emptyEqualityConstraintSet, qt.preds)) 
}
Run Code Online (Sandbox Code Playgroud)

虽然你应该重构去除那个可变状态.


som*_*ytt 7

以下是我们其他人的SLS报价:

必须部分地定义这种表达式的预期类型.它必须是scala.Functionk[S1, . . . , Sk, R]某些k> 0,或者 scala.PartialFunction[S1, R],参数类型S1 ,. ..,Sk必须完全确定,但结果类型R可能未确定.

否则,你回答了你的问题.