Skip to content

Instantly share code, notes, and snippets.

@hallettj
Created February 19, 2010 02:34
Show Gist options
  • Save hallettj/308344 to your computer and use it in GitHub Desktop.
Save hallettj/308344 to your computer and use it in GitHub Desktop.
/* 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