我有以下方法:
def firstAndLast[CC, A, That](seq: CC)(implicit asSeq: CC => Seq[A], cbf: CanBuildFrom[CC, A, That]): That = {
val b = cbf(seq)
b += seq.head
b += seq.last
b.result
}
请参阅:Method taking Seq[T] to return String rather than Seq[Char]了解原理。它在第一种情况下就像一个魅力,但在第二种情况下无法编译:
List("abc", "def") map {firstAndLast(_)}
List("abc", "def") map firstAndLast
,并提供:
error: No implicit view available from CC => Seq[A].
List("abc", "def") map firstAndLast
知道如何改进此声明以避免额外包装?似乎eta-expansion就是问题(?)
答案 0 :(得分:1)
对你的问题不是一个完整的答案,但我注意到这有效:
List("abc", "def") map firstAndLast[String, Char, String]
这意味着类型推断器无法确定firstAndLast
的正确类型参数,但我不知道如何修复它...
答案 1 :(得分:1)
虽然看起来很相似,但这些是不同的东西:
List("abc", "def") map {firstAndLast(_)}
// { x => firstAndLast(x) }
List("abc", "def") map firstAndLast
// firstAndLast, if it happened to be a function
现在,请注意编译器在第一种情况下如何轻松键入x
。在第二种情况下,它试图弄清(seq: CC)(implicit asSeq: CC => Seq[A], cbf: CanBuildFrom[CC, A, That])
如何被解释为Function1[String, ???]
,并且它失败了,因为缺少大量信息 - 即类型参数。
换句话说,在第一种情况下,编译器首先类型x
,因此,CC
,然后尝试找出其余部分。在第二种情况下,编译器试图同时找出所有类型参数。