我正在尝试解决some Scala problem set以了解该语言。我遇到问题11,我的解决方案无法编译。我的问题是:为什么Scala中这是非法的?
def countPackSingle[A](list: List[A]): List[Any] = {
pack(list) map {ls => {
case head :: Nil => head
case head :: tail => List(tail.size + 1, head)
}}
}
IntelliJ对此定义很满意,但编译器抱怨:
缺少扩展功能的参数类型
必须完全知道匿名函数的参数类型。 (SLS 8.5)预期类型是:?
pack(list) map {ls => { ^
我真的没有得到这条消息试图告诉我的内容。 scala编译器可以不推断ls
的类型吗?当我按ls: List[A]
指定类型时,问题仍然存在。
此时:为什么我在使用花括号ls
时可以指定参数{ }
的类型,但在使用括号( )
时却不能?直到今天,我正在寻找一个很好的资源来解释Scala的不同之处。到目前为止,我认为它只会产生real difference when using the literals to create parial functions via `case以及其他一些罕见的情况。
感谢您的帮助!
答案 0 :(得分:4)
这个结构:
{
case head :: Nil => head
case head :: tail => List(tail.size + 1, head)
}
是部分函数的语法糖,这就是编译器抛出此消息的原因,scalac认为您正在尝试创建PartilFunction[List[A], List[A]]
。要解决此问题,您有三种方法:
1)完成此操作以模式匹配构造:
pack(list) map { ls => ls match {
case head :: Nil => head
case head :: tail => List(tail.size + 1, head)
}
}
2)使用下划线语法:
pack(list) map { _ match {
case head :: Nil => head
case head :: tail => List(tail.size + 1, head)
}
}
实际上是一样的。现在,如果你愿意,你可以为ls归类一个类型,但是scala可以成功地推断它。
3)使用内联语法:
pack(list) map {
case head :: Nil => head
case head :: tail => List(tail.size + 1, head)
}
有可能因为PartialFunction
是Function
的子类,所以可以直接使用部分函数而不是普通函数。
结果类型List[Any]
中没有任何意义。 1)这种类型不好,导致你丢失所有的类型信息和2)你的功能不是尾递,所以你可以放弃它,让scalac为你推断它