Created
February 19, 2010 02:34
-
-
Save hallettj/308344 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Examples of using Stream to create lazily evaluated collections */ | |
def integersFrom(n: Int): Stream[Int] = | |
Stream.cons(n, integersFrom(n + 1)) | |
val naturals = integersFrom(1) | |
// From: http://www.scala-blogs.org/2007/12/project-euler-fun-in-scala.html | |
val fib: Stream[Int] = | |
Stream.cons(0, Stream.cons(1, fib.zip(fib.tail).map(p => p._1 + p._2))) | |
//scala> :load streams.scala | |
// | |
//scala> (naturals take 10).toList | |
//res0: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) | |
// | |
//scala> (fib take 10).toList | |
//res1: List[Int] = List(0, 1, 1, 2, 3, 5, 8, 13, 21, 34) | |
/* Probable signature of Stream.cons */ | |
//object Stream { | |
// ... | |
// def cons[A](hd: A, => Stream[A]): Stream[A] | |
// ... | |
//} | |
/* Thunk, a user-defined lazy structure for building mathematical expressions | |
* while deferring evaluation of those expressions */ | |
class Thunk(v: => Int) { | |
val value = v _ | |
def + (that: Thunk): Thunk = new Thunk(value() + that.value()) | |
def + (that: Int): Thunk = new Thunk(value() + that) | |
def * (that: Thunk): Thunk = new Thunk(value() * that.value()) | |
def * (that: Int): Thunk = new Thunk(value() * that) | |
def - (that: Thunk): Thunk = new Thunk(value() - that.value()) | |
def - (that: Int): Thunk = new Thunk(value() - that) | |
def / (that: Thunk): Thunk = new Thunk(value() / that.value()) | |
def / (that: Int): Thunk = new Thunk(value() / that) | |
} | |
def announceNum(n: Int): Int = { | |
println("Announcing: " + n) | |
n | |
} | |
def getNum(): Int = { | |
print("Enter an integer: ") | |
val n = readLine().toInt | |
println(n) | |
n | |
} | |
// scala> :load thunk.scala | |
// | |
// scala> val t = new Thunk(getNum()) + new Thunk(getNum()) | |
// t: Thunk = Thunk@49020230 | |
// | |
// scala> t.value() | |
// Enter an integer: 3 | |
// Enter an integer: 4 | |
// res13: Int = 7 | |
/* In dynamic languages you can use || and && to create short-circuited | |
* expressions with any types, not just booleans. Why not in Scala too? */ | |
class ShortCircuitable[A](v: A) { | |
private val falsyValues = List(Nil, "", 0, null) | |
def || (other: => A) = { | |
if (falsyValues.exists(_ == v)) other else v | |
} | |
def && (other: => A) = { | |
if (falsyValues.exists(_ == v)) v else other | |
} | |
} | |
implicit def any2ShortCircuitable[A](a: A): ShortCircuitable[A] = new ShortCircuitable(a) | |
//scala> :load short_circuitable.scala | |
// | |
//scala> val s: String = null | |
//s: String = null | |
// | |
//scala> s || "foo" | |
//res0: String = foo | |
// | |
//scala> s && "foo" | |
//res1: String = null | |
// | |
//scala> println("foo") && println("bar") | |
//foo | |
//bar | |
// | |
//scala> println("foo") || println("bar") | |
//foo |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment