Last active
July 8, 2016 22:20
-
-
Save mioalter/de57b36def578e91fdcb60f6b88a8148 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
/** | |
* Make a lazy value type as a thunk | |
*/ | |
/** | |
* Lazy value wihtout memoization | |
*/ | |
case class LazyVal[A](thunk : () => A) { | |
def value : A = this.thunk() | |
} | |
/** | |
* Lazy value with memoization | |
* Stores value as an Option[A] | |
* which is None if the value has not been evaluated yet | |
* and Some(value) if it has. | |
*/ | |
case class LazyVal2[A](thunk : () => A, value : Option[A]) { | |
def evaluate : LazyVal2[A] = | |
this.value match { | |
case Some(v) => this | |
case _ => LazyVal2(this.thunk, Some(this.thunk())) | |
} | |
} | |
/** | |
* Slow way to compute the nth Fibonacci number | |
*/ | |
def slowFibs(n : Int) : Int = | |
n match { | |
case n if n <= 2 => 1 | |
case _ => slowFibs(n - 1) + slowFibs(n - 2) | |
} | |
/** | |
* Fast way for reference | |
*/ | |
def fastFibs(n : Int) : BigInt = { | |
object fib { | |
val fibSequence : Stream[BigInt] = | |
1 #:: 1 #:: fibSequence.zip(fibSequence.drop(1)).map{case (a,b) => a + b} | |
} | |
fib.fibSequence.take(n).drop(n-1).head | |
} | |
def lazyFibs(n : Int) : LazyVal[Int] = | |
LazyVal(() => slowFibs(n)) | |
def lazyFibs2(n : Int) : LazyVal2[Int] = | |
LazyVal2(() => slowFibs(n), None) | |
def lazyFibs3(n : Int) : LazyVal2[BigInt] = | |
LazyVal2(() => fastFibs(n), None) | |
val l1 = lazyFibs2(45) | |
val l2 = lazyFibs3(500) | |
/** | |
* scala> l1 | |
* res38: LazyVal2[Int] = LazyVal2(<function0>,None) | |
* (instant, unevaluated) | |
* | |
* scala> l1.evaluate | |
* res39: LazyVal2[Int] = LazyVal2(<function0>,Some(1134903170)) | |
* (takes a few seconds to evaluate) | |
* | |
* scala> l2 | |
* res40: LazyVal2[BigInt] = LazyVal2(<function0>,None) | |
* (instant, unevaluated) | |
* | |
* scala> l2.evaluate | |
* res41: LazyVal2[BigInt] = LazyVal2(<function0>,Some(139423224561697880139724382870407283950070256587697307264108962948325571622863290691557658876222521294125)) | |
* (evalutes pretty fast) | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment