Chapter 3, Exercise 5, Thinking in Scala
For this exercise, the wrinkle is
that Scala's "for" has no break statement.
We simulate it here, with an exception. The bodies of ifs
and whiles are already anonymous nested functions anyway;
and that is the kind of thing we are passing as the second ("body") argument to the tfor
function.
case class breakEx extends Throwable;
object c3x5 {
def break = { throw new breakEx(); }
def tfor (iter: Iterator[Int]) (def body: Int => unit): unit = {
try {
while( iter.hasNext ) {
body(iter.next);
}
}
catch { case breakEx => }
}
def main ( args: Array[String] ) = {
tfor (Iterator.range(1,101) ) { i =>
if (i == 47) { break; }
Console.println( i.toString() );
}
}
}
This will not satisfy situations where one wants to use the final value of the iterator variable, after the loop completes.
A strategy similar to the following should suffice for those cases:
case class breakEx extends Throwable;
object c3x5n {
def break = { throw new breakEx(); }
def tfor (iter: Iterator[Int]) (def body: Int => unit): unit = {
try {
while( iter.hasNext ) {
body(iter.next);
}
}
catch { case breakEx => }
}
def main ( args: Array[String] ) = {
var j : Int = _;
tfor (Iterator.range(1,101) ) { i =>
if (i == 47) { break; }
Console.println( i.toString() );
j = i;
}
Console.println( "After the tfor, j is " + j.toString() );
}
}
5:23:43 PM