class MyRange(val start: Int, val end: Int) extends Iterable[Int] {
override def toString = start + ".." + end
def iterator = new Iterator[Int] {
private var _current = start
def reset { _current = start }
def current = _current
def atEnd = current > end
def advance { _current = _current + 1 }
}
}
class MyExclusiveEndedRange(val start: Int, val end: Int) extends MyRange(start, end) {
override def toString = start + "..." + end
override def iterator = new Iterator[Int] {
private var _current = start
def reset { _current = start }
def current = _current
def atEnd = current >= end
def advance { _current = _current + 1 }
}
}
Sponsor Sponsor
wtd
Posted: Wed Jun 06, 2007 12:55 pm Post subject: Re: [Scala] A little code
code:
// Let's add a method to Iterable. It takes, as a paremeter, a function.
trait Iterable[A] {
def iterator: Iterator[A]
def doForAll(f: A => Unit) {
val i = iterator
while (i.hasMore) {
f(i.current)
i.advance
}
}
}
// Now, let's rewrite the loop.
val r = new MyRange(1, 4)
r.doForAll((x: Int) => Console.println(x))
// Or perhaps...
val r = new MyRange(1, 4)
r.doForAll { case x => Console.println(x) }
// Or using special syntax for binary methods, we can get rid of all of the periods.
new MyRange(1, 4) doForAll { case x => Console println x }
richcash
Posted: Wed Jun 06, 2007 10:03 pm Post subject: Re: [Scala] A little code
Great introduction!
I like the keywords override and trait.
wtd wrote:
code:
// Or using special syntax for binary methods, we can get rid of all of the periods.
new MyRange(1, 4) doForAll { case x => Console println x }
Wow, that is cool. But isn't doForAll a unary method, not a binary method?
wtd
Posted: Wed Jun 06, 2007 11:12 pm Post subject: RE:[Scala] A little code
I suppose you might classify it that way as well. Binary in this case because it has both a receiver and an argument.
richcash
Posted: Thu Jun 07, 2007 12:58 am Post subject: Re: [Scala] A little code
wtd wrote:
I suppose you might classify it that way as well. Binary in this case because it has both a receiver and an argument.
Oh, now I see what you mean. Thanks for clarifying.
wtd
Posted: Thu Jun 07, 2007 10:54 am Post subject: RE:[Scala] A little code
Another possibility for that last one:
code:
new MyRange(1, 4) doForAll (Console println _)
wtd
Posted: Thu Jun 07, 2007 2:57 pm Post subject: RE:[Scala] A little code
code:
// Turns out, there're generic Iterable and Iterator traits already
// defined as part of Scala's standard library.
class MyRange(val start: Int, val end: Int) extends Iterable[Int] {
def elements = new Iterator[Int] {
private var current = start
def hasNext = current <= end
def next = {
val c = current
current += 1
c
}
}
}
// Now we can write our while loop.
val r = new MyRange(1, 4)
val i = r.elements
while (i.hasNext) {
Console.println(i.next)
}
// But you'd think it would be easier.
for (val x <- new MyRange(1, 4))
Console.println(x)
// But what if we only want to print the even numbers?
val r = new MyRange(1, 4)
val i = r.elements
while (i.hasNext) {
val x = i.next
if (x % 2 == 0)
Console.println(x)
}
// I said something about "easier"
for (val x <- new MyRange(1, 4))
if (x % 2 == 0)
Console.println(x)
// Ahem... *easier*
for (val x <- new MyRange(1, 4) if x % 2 == 0)
Console.println(x)
Posted: Thu Jun 07, 2007 3:26 pm Post subject: RE:[Scala] A little code
code:
// Being picky.
for (val x <- new MyRange(1, 55)) {
if (x == 42)
Console println "42! The answer! But what is the question?"
else if (x % 2 == 0)
Console println x
else
Console println "Better luck next time."
}
// Let's inject some pattern-matching.
for (val x <- new MyRange(1, 55)) {
x match {
case 42 => Console println "42! The answer! But what is the question?"
case _ =>
if (x % 2 == 0)
Console println x
else
Console println "Better luck next time."
}
}
// Or perhaps...
new MyRange(1, 4) foreach {
case 42 => Console println "42! The answer! But what is the question?"
case _ =>
if (x % 2 == 0)
Console println x
else
Console println "Better luck next time."
}
Sponsor Sponsor
Clayton
Posted: Thu Jun 07, 2007 3:28 pm Post subject: RE:[Scala] A little code
I must ask, I've noticed you use an underscore quite a bit, like in here:
scala:
case _ =>
if (x % 2 == 0)
Console println x
else
Console println "Better luck next time."
What exactly does it mean?
wtd
Posted: Thu Jun 07, 2007 3:31 pm Post subject: RE:[Scala] A little code
In that context, it is a nameless pattern that matches anything that a previous pattern has not.
Clayton
Posted: Thu Jun 07, 2007 3:32 pm Post subject: RE:[Scala] A little code
So in essence a safeguard for something that slips through?
wtd
Posted: Thu Jun 07, 2007 3:33 pm Post subject: RE:[Scala] A little code
Yes. Essentially analogous to "default" in Java's "switch" statement.
Clayton
Posted: Thu Jun 07, 2007 3:35 pm Post subject: RE:[Scala] A little code
Ah, excellent.
Now, I may have missed something about this earlier, but this:
code:
val x <- new MyRange(1, 55)
confuses me a bit, care to explain?
wtd
Posted: Thu Jun 07, 2007 3:39 pm Post subject: RE:[Scala] A little code
It is part of the for comprehension.
We assign each element of the object created by "new MyRange(1, 55)" to the constant "x". The keyword "var" could also be used, allowing x to be modified within the body of the comprehension.
Clayton
Posted: Thu Jun 07, 2007 3:41 pm Post subject: RE:[Scala] A little code
Ah, alright. I think the '<-' from the "new MyRange(1, 55)" kind of obscured the fact that that was an assignation. I have to admit, Scala looks pretty darn cool.