Despite thinking and reading for several hours I don't understand the error produced by the following code when compiled with version 2.11.6 of the Scala compiler:
object Test
{
type F = (String) => Set[String]
def n_ary(f: (F, F) => F) = {
def n_ary_f(x: F, args: F*): F =
(t: String) =>
if (args.isEmpty) x(t)
else f(x, n_ary_f(args.head, args.tail: _*))(t)
n_ary_f _
}
def seq(x: F, y: F) =
(t: String) =>
(for(c <- x(t).toIterator; d <- y(c).toIterator)
yield d).toSet
def seq_n(x: F, y: F*): F =
n_ary(seq)(x, y: _*)
}
The compiler's output is:
params.scala:17: error: type mismatch;
found : Seq[Test.F]
(which expands to) Seq[String => Set[String]]
required: Seq[Seq[Test.F]]
(which expands to) Seq[Seq[String => Set[String]]]
n_ary(seq)(x, y: _*)
^
When compiling the code without the _*
behind the argument y
in the call to n_ary(sec)
on the last line there is no error. Nethertheless this seems kind of wrong to me. Version 2.9.2 of the Scala compiler actually produces the following error output when used to compile my code after applying the aforementioned modification to the last line:
params.scala:21: error: type mismatch;
found : String => Set[String]*
required: String => Set[String]
n_ary(seq)(x, y)
^
In my opinion this error message makes sense, because n_ary's second argument is not a Seq[String => Set[String]]
, but a String => Set[String]
, that could also be left out or repeated once or more times. But to avoid this error I would have to undo my change and use the code as listed above leaving me with the aforementioned error when compiled with the current version of scalac ...
Could someone please explain what I am getting wrong here, especially concerning the error produced by the current compiler version?