Writing a generalized filling method

I am trying to write a generic fill method, and here 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 shared collections except arrays. How to make this code work with arrays?

+6
source share
3 answers

If you do not mind creating an additional object, there are

 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 } } 

This does not bypass the objection (2), but the use is pleasant:

 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) 
+10
source

You can slightly change the syntax of a Rex solution:

 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] 

Since the operator designation is allowed only for parentheses, we cannot omit the parentheses.

+1
source

I used the Rex solution here using the Builder ++= method. Use any collection, perform on it all the operations that you want to perform, and then finally add it to the constructor object and then execute its result.

 scala> def fill[CC[_]](n: Int) = new { | def apply[A](elem: => A) | (implicit cbf: CanBuildFrom[Nothing, A, CC[A]]) = { | val b = cbf.apply | b ++= Vector.fill(n)(elem) | b.result | } | } fill: [CC[_]](n: Int)java.lang.Object{def apply[A](elem: => A)(implicit cbf: sca la.collection.generic.CanBuildFrom[Nothing,A,CC[A]]): CC[A]} scala> fill[List](3)("hullo") res8: List[java.lang.String] = List(hullo, hullo, hullo) 
0
source

Source: https://habr.com/ru/post/896656/


All Articles