Skip to content

Instantly share code, notes, and snippets.

@lazyvalue
Created May 27, 2015 08:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lazyvalue/88640d4bad2d3b65faa8 to your computer and use it in GitHub Desktop.
Save lazyvalue/88640d4bad2d3b65faa8 to your computer and use it in GitHub Desktop.
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