Created
July 13, 2015 23:33
-
-
Save lazyvalue/833b40ba538d4f0773b2 to your computer and use it in GitHub Desktop.
scala state and io stuff
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 | |
// 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 mainz(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 mainz(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 mainz(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 | |
def makeComputation = 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 mainz(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 mainz(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