Is there a brief syntax for executing a block n times in Scala?
You could easily define one using Pimp My Library pattern.
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
With scalaz 5:
doSomething.replicateM[List](n)
With scalaz 6:
n times doSomething
And that works as you would expect with most types (more precisely, for every monoid):
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!
You could also say doSomething replicateM_ 5
which only works if your doSomething
is an idiomatic value (see Applicative
). It has better type-safety, since you can do this:
scala> putStrLn("Foo") replicateM_ 5
res6: scalaz.effects.IO[Unit] = scalaz.effects.IO$$anon$2@8fe8ee7
but not this:
scala> { System.exit(0) } replicateM_ 5
<console>:15: error: value replicateM_ is not a member of Unit
Let me see you pull that off in Ruby.
The Range class has a foreach method on it that I think is just what you need. For example, this:
0.to(5).foreach(println(_))
produced
0
1
2
3
4
5