Reputation: 105
I want to make some function for unspecified number of arguments of function
for example
scala> def test(fx: (String*) => Boolean, arg: String*): Boolean = fx(arg: _*)
test: (fx: String* => Boolean, arg: String*)Boolean
scala> def AA(arg1: String, arg2: String) :Boolean = {
println ("Arg1 : " + arg1 + " Arg2 : " + arg2)
true}
AA: (arg1: String, arg2: String)Boolean
scala> test(AA,"ASDF","BBBB")
<console>:10: error: type mismatch;
found : (String, String) => Boolean
required: String* => Boolean
test(AA,"ASDF","BBBB")
^
How can I solve this problem??
Upvotes: 1
Views: 572
Reputation: 9820
This could be done using shapeless with ProductArgs
and something similar to my answer to another question.
import shapeless.{HList, ProductArgs}
import shapeless.ops.hlist.IsHCons
import shapeless.ops.function.FnToProduct
import shapeless.syntax.std.function._
object test extends ProductArgs {
def applyProduct[L <: HList, NarrowArgs <: HList, Args <: HList, F, R](
l: L
)(implicit
ihc: IsHCons.Aux[L, F, NarrowArgs],
ftp: FnToProduct.Aux[F, Args => R],
ev: NarrowArgs <:< Args
): R = {
val (func, args) = (l.head, l.tail)
func.toProduct(args)
}
}
Which you can use as :
def aa(s1: String) = s1.length
def bb(s1: String, s2: String) = s1 * s2.length
test(aa _, "foo") // Int = 3
test(bb _, "foo", "bar") // String = foofoofoo
// test(aa _, "foo", "bar") doesn't compile
Extending ProductArgs
transforms or test(aa _, "foo")
(which is actually test.apply(aa _, "foo")
) to test.applyProduct((aa _) :: "foo" :: HNil)
. In applyProduct
we check that the HList
consists of a function and valid arguments.
We shouldn't need the NarrowArgs <:< Args
, but ProductArgs
seems to give the same result as SingletonProductArgs
.
Upvotes: 3
Reputation: 4256
It's because AA
does not accept variable number of arguments, change it to:
def AA(args: String*) :Boolean
Upvotes: 0