我有一个函数文字
{case QualifiedType(preds, ty) =>
t.ty = ty ;
Some((emptyEqualityConstraintSet,preds)) }
这会导致错误消息
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)]
我查看了SLS 8.5 ,但没有找到解释。
如果我自己将函数扩展为
{(qt : QualifiedType) =>
qt match {case QualifiedType(preds, ty) =>
t.ty = ty ;
Some((emptyEqualityConstraintSet,preds)) }}
错误消失。
(a) 为什么这是一个错误?
(b) 我可以采取什么措施来修复它?
我尝试了明显的修复方法,即在模式和 => 之间添加 : QualifiedType
,但这是一个语法错误。
我注意到的一件事是上下文会产生影响。如果我使用函数文字作为声明为期望 QualifiedType => B
的函数的参数,则不会出现错误。但是,如果我将它用作需要 A => B
的函数的参数,则会出现错误。我预计这里发生的情况是,由于该模式可以想象应用于类型是 QualifiedType 父类(super class)型的对象,因此编译器不愿意在不保证该函数不会应用于的情况下分配明显的类型任何不是 QualifiedType 的东西。我真正想要的是能够编写 {QualifiedType( preds, ty) => ...}
并使其与 Haskell 的 \QualifiedType(preds,ty) -> ...
含义相同。
最佳答案
{ case X(x) => ... }
是一个部分函数,但编译器仍然不知道你的输入类型是什么,除了它是 的父类(super class)型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
正如您可能已经注意到的,在这里使用函数文字/模式匹配是毫无意义的。在您的情况下,您似乎只需要一个常规方法:
def whatever(qt: QualifiedType) = {
t.ty = qt.ty
Some((emptyEqualityConstraintSet, qt.preds))
}
尽管您应该重构以删除该可变状态。
关于scala - 匿名函数的参数类型必须是完全已知的。 (SLS 8.5),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12869251/