I am trying to write a generic fill
method, and following is what I have come up with so far:
scala> import collection.generic.{GenericTraversableTemplate => GTT}
import collection.generic.{GenericTraversableTemplate=>GTT}
scala> import collection.generic.{TraversableFactory => TF}
import collection.generic.{TraversableFactory=>TF}
scala> def fill[A, CC[X] <: Traversable[X] with GTT[X, CC]]
| (n: Int)(elem: => A)(tf: TF[CC]) = tf.fill(n)(elem)
fill: [A, CC[X] <: Traversable[X] with scala.collection.generic.GenericTraversab
leTemplate[X,CC]](n: Int)(elem: => A)(tf: scala.collection.generic.TraversableFa
ctory[CC])CC[A]
scala> fill(3)('d')(List)
res42: List[Char] = List(d, d, d)
This works with all traversable collections except arrays. How do I make this code work with arrays?
Example: Create a Generics Method We can call the generics method by placing the actual type <String> and <Integer> inside the bracket before the method name. demo. <String>genericMethod("Java Programming"); demo. <Integer>genericMethod(25);
For static generic methods, the type parameter section must appear before the method's return type. The complete syntax for invoking this method would be: Pair<Integer, String> p1 = new Pair<>(1, "apple"); Pair<Integer, String> p2 = new Pair<>(2, "pear"); boolean same = Util. <Integer, String>compare(p1, p2);
What are generic methods? Explanation: Generic methods are methods that introduce their own type parameters. This is similar to declaring a generic type, but the type parameter scope is limited to the method where it is declared. Static and non-static generic methods are allowed, as well as generic class constructors.
Generic methods allow type parameters to be used to express dependencies among the types of one or more arguments to a method and/or its return type. If there isn't such a dependency, a generic method should not be used. It is possible to use both generic methods and wildcards in tandem. Here is the method Collections.
If you don't mind creating an extra object, there's
def fill[CC[_]](n: Int) = new {
def apply[A](elem: => A)(implicit cbf: CanBuildFrom[Nothing, A, CC[A]]) = {
val b = cbf()
1 to n foreach { _ => b += elem }
b.result
}
}
It doesn't get around objection (2), but the usage is nice:
scala> fill[List](3)("wish")
res0: List[java.lang.String] = List(wish, wish, wish)
scala> fill[Array](3)("wish")
res1: Array[java.lang.String] = Array(wish, wish, wish)
It is possible to change the syntax of Rex' solution a little bit:
class Filler(n: Int) {
def timesOf[A](elem: => A) = new Builder[A](elem)
class Builder[A](elem: => A) {
import scala.collection.generic.CanBuildFrom
def fillIn[CC[_]](implicit cbf: CanBuildFrom[Nothing, A, CC[A]]) = {
val b = cbf()
for (_ <- 1 to n) b += elem
b.result
}
}
}
implicit def int2Filler(n: Int) = new Filler(n)
// use as
(3 timesOf true).fillIn[List]
Because operator notation is only allowed for parentheses, we can't omit the brackets.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With