tutorial software renault fungicida examples constructora blanquerna scala

software - scala tutorial



¿Hay una breve sintaxis para ejecutar un bloque n veces en Scala? (5)

Me encuentro escribiendo código como este cuando quiero repetir algunas ejecuciones n veces:

for (i <- 1 to n) { doSomething() }

Estoy buscando una sintaxis más corta como esta:

n.times(doSomething())

¿Algo como esto existe en Scala ya?

EDITAR

Pensé en usar el método foreach () de Range, pero luego el bloque necesita tomar un parámetro que nunca usa.

(1 to n).foreach(ignored => doSomething())


Con scalaz 5 :

doSomething.replicateM[List](n)

Con scalaz 6 :

n times doSomething

Y eso funciona como se esperaría con la mayoría de los tipos (más precisamente, para cada monoide ):

scala> import scalaz._; import Scalaz._; import effects._; import scalaz._ import Scalaz._ import effects._ scala> 5 times "foo" res0: java.lang.String = foofoofoofoofoo scala> 5 times List(1,2) res1: List[Int] = List(1, 2, 1, 2, 1, 2, 1, 2, 1, 2) scala> 5 times 10 res2: Int = 50 scala> 5 times ((x: Int) => x + 1).endo res3: scalaz.Endo[Int] = <function1> scala> res3(10) res4: Int = 15 scala> 5 times putStrLn("Hello, World!") res5: scalaz.effects.IO[Unit] = scalaz.effects.IO$$anon$2@36659c23 scala> res5.unsafePerformIO Hello, World! Hello, World! Hello, World! Hello, World! Hello, World!

También podría decir doSomething replicateM_ 5 que solo funciona si doSomething es un valor idiomático (ver Applicative ). Tiene una seguridad de tipo mejor, ya que puedes hacer esto:

scala> putStrLn("Foo") replicateM_ 5 res6: scalaz.effects.IO[Unit] = scalaz.effects.IO$$anon$2@8fe8ee7

pero no esto:

scala> { System.exit(0) } replicateM_ 5 <console>:15: error: value replicateM_ is not a member of Unit

Déjame ver que lo saques en Ruby.


La clase Range tiene un método foreach que creo que es justo lo que necesita. Por ejemplo, esto:

0.to(5).foreach(println(_))

producido

0
1
2
3
4
5


No estoy al tanto de nada en la biblioteca. Puede definir una conversión y clase implícita de utilidad que puede importar según sea necesario.

class TimesRepeat(n:Int) { def timesRepeat(block: => Unit): Unit = (1 to n) foreach { i => block } } object TimesRepeat { implicit def toTimesRepeat(n:Int) = new TimesRepeat(n) } import TimesRepeat._ 3.timesRepeat(println("foo"))

Rahul acaba de publicar una respuesta similar mientras escribía esto ...


Podrías definir fácilmente uno usando el patrón Pimp My Library.

scala> implicit def intWithTimes(n: Int) = new { | def times(f: => Unit) = 1 to n foreach {_ => f} | } intWithTimes: (n: Int)java.lang.Object{def times(f: => Unit): Unit} scala> 5 times { | println("Hello World") | } Hello World Hello World Hello World Hello World Hello World


Puede ser tan simple como esto:

scala> def times(n:Int)( code: => Unit ) { for (i <- 1 to n) code } times: (n: Int)(code: => Unit)Unit scala> times(5) {println("here")} here here here here here