Created
May 27, 2015 08:31
-
-
Save lazyvalue/88640d4bad2d3b65faa8 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
package ground | |
// Show that println and Unit are not the same. | |
// Why pure IO? | |
// Trampoline | |
// IO values and interpreters | |
object UnitIsNotUnit { | |
// Side effects are extremely hard to reason about. | |
// The only way you can tell when they are executed is by following imperative code | |
// and its step by step instructions. Furthermore, they are prone to errors, and a null-operation is the same | |
// as an actual side effect. | |
def talkToServer: Unit = { | |
println("hi server!") | |
} | |
def doNothingInteresting: Unit = { | |
4 + 6 | |
() | |
} | |
(doNothingInteresting == talkToServer) == true | |
} | |
object DumbTediumBuzz { | |
def even(sum: Int, lst: List[Int]): Int = lst match { | |
case Nil => sum | |
case x :: xs => odd(sum + x, xs) | |
} | |
def odd(sum: Int, lst: List[Int]): Int = lst match { | |
case Nil => sum | |
case x :: xs => even(sum, xs) | |
} | |
def main(args: Array[String]) { | |
val random = new java.util.Random(23) | |
val randomizedList = List.fill(7000)(random.nextInt) | |
val resultFromSum = even(0, randomizedList) | |
// SPOILER ALERT! STACKOVERFLOW ERROR | |
println(resultFromSum) | |
} | |
} | |
object SmartTediumBuzz { | |
sealed trait Trampoline[A] | |
case class More[A](f: () => Trampoline[A]) extends Trampoline[A] | |
case class Done[A](v: A) extends Trampoline[A] | |
def runTrampoline[A](tramp: Trampoline[A]): A = tramp match { | |
case Done(v) => v | |
case More(m) => runTrampoline(m()) | |
} | |
def even(sum: Int, lst: List[Int]): Trampoline[Int] = lst match { | |
case Nil => Done(sum) | |
case x :: xs => More(() => odd(sum + x, xs)) | |
} | |
def odd(sum: Int, lst: List[Int]): Trampoline[Int] = lst match { | |
case Nil => Done(sum) | |
case x :: xs => More(() => even(sum, xs)) | |
} | |
def main(args: Array[String]) { | |
val random = new java.util.Random(23) | |
val randomizedList = List.fill(7000)(random.nextInt) | |
val computation: Trampoline[Int] = even(0, randomizedList) | |
val resultFromSum = runTrampoline(computation) | |
println(resultFromSum) | |
} | |
// And we can write implementations of map and flatMap for this | |
} | |
object ScalazTediumBuzz { | |
import scalaz._, Scalaz._ | |
import Free._ | |
def even(sum: Int, lst: List[Int]): Trampoline[Int] = lst match { | |
case Nil => return_(sum) | |
case x :: xs => suspend(odd(sum + x, xs)) | |
} | |
def odd(sum: Int, lst: List[Int]): Trampoline[Int] = lst match { | |
case Nil => return_(sum) | |
case x :: xs => suspend(even(sum, xs)) | |
} | |
def main(args: Array[String]) { | |
val random = new java.util.Random(23) | |
val randomizedList = List.fill(7000)(random.nextInt) | |
val setup = even(0, randomizedList) | |
val result = setup.run | |
println(result) | |
} | |
} | |
object LazyLazyIOExample { | |
import scalaz._, Scalaz._, effect._ | |
import IO._ | |
// Note the val | |
val makeComputation: IO[Unit] = for { | |
_ <- putStrLn("what is your name?: ") | |
name <- readLn | |
_ <- handleName(name) | |
} yield () | |
def handleName(name: String): IO[Unit] = | |
if(name == "exit") putStrLn("Thank you for playing.") | |
else for { | |
_ <- putStrLn("i have heard better names than that, " + name) | |
_ <- makeComputation | |
} yield () | |
def main(args: Array[String]) { | |
makeComputation.unsafePerformIO | |
} | |
} | |
object StateTransformerTediumBuzz { | |
import scalaz._ | |
import scalaz.State._ | |
import scalaz.StateT | |
import scalaz.effect.IO | |
import scalaz.effect.LiftIO | |
import scalaz.effect.MonadIO | |
import scalaz.effect.stateTEffect.StateTMonadIO | |
import Kleisli._ | |
case class BuzzState(value: Int, work: List[Int]) | |
type BuzzMonad[X] = StateT[IO, BuzzState, X] | |
def even: BuzzMonad[Int] = for { | |
state <- get[BuzzState].lift[IO] | |
_ <- IO.putStrLn(s"EVEN: ${state.value} with ${state.work.length} left to go").liftIO[BuzzMonad] | |
_ <- if(state.work == Nil) put(state).lift[IO] else | |
for { | |
_ <- put(state.copy(state.value + state.work.head, state.work.tail)).lift[IO] | |
_ <- odd | |
newState <- get[BuzzState].lift[IO] | |
} yield newState.value | |
} yield state.value | |
def odd: BuzzMonad[Int] = for { | |
state <- get[BuzzState].lift[IO] | |
_ <- IO.putStrLn(s"ODD: ${state.value} with ${state.work.length} left to go").liftIO[BuzzMonad] | |
_ <- if(state.work == Nil) put(state).lift[IO] else | |
for { | |
_ <- put(state.copy(state.value, state.work.tail)).lift[IO] | |
_ <- even | |
newState <- get[BuzzState].lift[IO] | |
} yield newState.value | |
} yield state.value | |
def main(args: Array[String]) { | |
val random = new java.util.Random(23) | |
val randomizedList = List.fill(7000)(random.nextInt) | |
val result = even.run(BuzzState(0, randomizedList)).unsafePerformIO | |
println(result) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment