Reputation: 340973
I have a following method:
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
}
See: Method taking Seq[T] to return String rather than Seq[Char] for rationale. It works like a charm in the first case but fails to compile in the second:
List("abc", "def") map {firstAndLast(_)}
List("abc", "def") map firstAndLast
Giving:
error: No implicit view available from CC => Seq[A].
List("abc", "def") map firstAndLast
Any idea how to improve this declaration to avoid extra wrapping? Seems like eta-expansion is the problem (?)
Upvotes: 5
Views: 174
Reputation: 297275
Though they look similar, these are different things:
List("abc", "def") map {firstAndLast(_)}
// { x => firstAndLast(x) }
List("abc", "def") map firstAndLast
// firstAndLast, if it happened to be a function
Now, note how the compiler can easily type x
in the first case. In the second case, it is trying to figure out how (seq: CC)(implicit asSeq: CC => Seq[A], cbf: CanBuildFrom[CC, A, That])
might be interpreted as Function1[String, ???]
, and it is failing because there's a lot of information missing -- namely, the type parameters.
In other words, in the first case, the compiler first types x
, and, therefore, CC
, and then tries to figure out the rest. In the second case, the compiler is trying to figure out all of the type parameters at the same time.
Upvotes: 1
Reputation: 60006
Not a full answer to your question, but I’ve just noticed that this works:
List("abc", "def") map firstAndLast[String, Char, String]
It then means that the type inferencer is having trouble determining the right type parameters for firstAndLast
, but I wouldn’t know how to fix it…
Upvotes: 1