Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Scala, can I (would some SIP allow me to) specify only certain type parameters of a generic method?

When calling methods with type parameters in Scala, I often try to arrange the code so that the type inferencer can find out itself about the type parameters and not need me to fill them out. In some circumstances, it fails and I have to provide them manually.

Most of the time, this is not a problem, but for methods with several type parameters (e.g., most methods requiring an implicit CanBuildFrom), I was wondering whether there was a way to help the type inferencer by giving it only one of the needed type parameters, and asking it to try and guess the other ones. It looks like internally, it must be doing such things anyway, since it sometimes produces error messages of the form “expected type A[B, ?] but got A[C, D]”, which would means that of the two type parameters of A, the it could find out the first one B but has no info about the second one.

Use case: Tomasz’s question, where this code:

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
}

cannot be called with List("abc", "def") map firstAndLast, but this would work:

List("abc", "def") map firstAndLast[String, Char, String]

In this example, my question boils down to: is there any way to tell the type inferencer that the CC parameter should be String, and ask it to find out itself about A and That? Something like, in essence,

List("abc", "def") map firstAndLast[CC = String]

or

List("abc", "def") map firstAndLast[String, <guess>, <guess>]

I know these lines don’t work; I’m looking for a workaround (or for pointers to future language features that have been discussed and which could lead to this).

like image 776
Jean-Philippe Pellet Avatar asked Nov 14 '22 04:11

Jean-Philippe Pellet


1 Answers

No, you can't. There's type lambdas and type itself which would serve for types (as in classes and traits), but not for type parameters. For example:

// Declaring a type alias
type StringMap[Elem] = Map[String, Elem]

// Calling an `def f[M[_]]` but passing a `Map`
f[({type l[A]=Map[String,A]})#l]

// note that f could also be called like this:
f[StringMap]
like image 164
Daniel C. Sobral Avatar answered Dec 05 '22 04:12

Daniel C. Sobral