Skip to content

Instantly share code, notes, and snippets.

@dcastro
Last active August 16, 2018 14:10
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 dcastro/651c654dd40be802fe74279c4fd8382b to your computer and use it in GitHub Desktop.
Save dcastro/651c654dd40be802fe74279c4fd8382b to your computer and use it in GitHub Desktop.
import scala.io.StdIn._
object CustomIO extends App {
/**
* Slides: https://docs.google.com/presentation/d/15O8fzIEa85a8S_vk6N3b_S8F4IYbrFkLOXmtwbcy0cQ
*/
case class IO[A](unsafeRun: () => A) {
def map[B](f: A => B): IO[B] =
IO(() => f(this.unsafeRun()))
def flatMap[B](f: A => IO[B]): IO[B] =
IO(() => f(this.unsafeRun()).unsafeRun())
}
def print(line: String): IO[Unit] =
IO(() => println(line))
val read: IO[String] =
IO(() => readLine)
val io =
for {
_ <- print("Enter your name:")
str <- read
upper = str.toUpperCase
_ <- print(s"Your name in uppercase: $upper")
} yield ()
io.unsafeRun()
}
import cats.implicits._
import cats.effect._
import scala.io.StdIn._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent._
object CatsIO extends App {
/**
* Slides: https://docs.google.com/presentation/d/15O8fzIEa85a8S_vk6N3b_S8F4IYbrFkLOXmtwbcy0cQ
*/
val io =
for {
_ <- IO(println("Enter your name:"))
str <- IO(readLine)
upper = str.toUpperCase
_ <- IO(println(s"Your name in uppercase: $upper"))
} yield ()
io.unsafeRunSync()
// composing io actions sequentially
val sayHello = IO(println("hello"))
val sayWorld = IO(println("world"))
val read = IO(readLine)
for {
_ <- sayHello
_ <- sayWorld
} yield ()
sayHello *> sayWorld
List(sayHello, sayWorld).sequence
(read, read).mapN { _ + _ }
// composing io actions in parallel
List(sayHello, sayWorld).parSequence
(read, read).parMapN { _ + _ }
// failing, short-circuiting
for {
name <- IO(readLine("Enter your name:"))
_ <- name match {
case "exit" => IO.raiseError(new Exception("exiting"))
case _ => IO.unit
}
_ <- IO(println(s"Your name in uppercase: ${name.toUpperCase}"))
} yield ()
// converting futures to io
val readFromDb: Future[Int] = Future(3)
val readFromDB2: IO[Int] = IO.fromFuture(IO(readFromDb))
// manipulating IO as values
def nTimes[A](io: IO[A], n: Int): IO[List[A]] =
List.fill(n)(io).sequence
def forever[A](io: IO[A]): IO[A] =
io >> forever(io)
def retry[A](io: IO[A]): IO[A] =
io orElse retry(io)
def retryN[A](io: IO[A], times: Int): IO[A] =
if (times <= 1)
io
else
io orElse retryN(io, times - 1)
}
lazy val root = (project in file(".")).
settings(
inThisBuild(List(
organization := "com.example",
scalaVersion := "2.12.3",
version := "0.1.0-SNAPSHOT"
)),
name := "Hello",
libraryDependencies ++=
List(
scalaTest % Test,
"org.typelevel" %% "cats-core" % "1.2.0",
"org.typelevel" %% "cats-effect" % "1.0.0-RC2-93ac33d"
)
)
initialCommands in Compile in console :=
"""import notes._
|import cats.implicits._
|import cats.effect._
""".stripMargin
scalacOptions ++= Seq(
"-deprecation", // Emit warning and location for usages of deprecated APIs.
"-encoding", "utf-8", // Specify character encoding used by source files.
"-explaintypes", // Explain type errors in more detail.
"-feature", // Emit warning and location for usages of features that should be imported explicitly.
"-language:existentials", // Existential types (besides wildcard types) can be written and inferred
"-language:experimental.macros", // Allow macro definition (besides implementation and application)
"-language:higherKinds", // Allow higher-kinded types
"-language:implicitConversions", // Allow definition of implicit functions called views
"-unchecked", // Enable additional warnings where generated code depends on assumptions.
"-Xcheckinit", // Wrap field accessors to throw an exception on uninitialized access.
"-Xfuture", // Turn on future language features.
"-Xlint:adapted-args", // Warn if an argument list is modified to match the receiver.
"-Xlint:by-name-right-associative", // By-name parameter of right associative operator.
"-Xlint:constant", // Evaluation of a constant arithmetic expression results in an error.
"-Xlint:delayedinit-select", // Selecting member of DelayedInit.
"-Xlint:doc-detached", // A Scaladoc comment appears to be detached from its element.
"-Xlint:inaccessible", // Warn about inaccessible types in method signatures.
"-Xlint:infer-any", // Warn when a type argument is inferred to be `Any`.
"-Xlint:missing-interpolator", // A string literal appears to be missing an interpolator id.
"-Xlint:nullary-override", // Warn when non-nullary `def f()' overrides nullary `def f'.
"-Xlint:nullary-unit", // Warn when nullary methods return Unit.
"-Xlint:option-implicit", // Option.apply used implicit view.
"-Xlint:package-object-classes", // Class or object defined in package object.
"-Xlint:poly-implicit-overload", // Parameterized overloaded implicit methods are not visible as view bounds.
"-Xlint:private-shadow", // A private field (or class parameter) shadows a superclass field.
"-Xlint:stars-align", // Pattern sequence wildcard must align with sequence component.
"-Xlint:type-parameter-shadow", // A local type parameter shadows a type already in scope.
"-Xlint:unsound-match", // Pattern match may not be typesafe.
"-Yno-adapted-args", // Do not adapt an argument list (either by inserting () or creating a tuple) to match the receiver.
"-Ypartial-unification", // Enable partial unification in type constructor inference
"-Ywarn-dead-code", // Warn when dead code is identified.
"-Ywarn-extra-implicit", // Warn when more than one implicit parameter section is defined.
"-Ywarn-inaccessible", // Warn about inaccessible types in method signatures.
"-Ywarn-infer-any", // Warn when a type argument is inferred to be `Any`.
"-Ywarn-nullary-override", // Warn when non-nullary `def f()' overrides nullary `def f'.
"-Ywarn-nullary-unit", // Warn when nullary methods return Unit.
"-Ywarn-numeric-widen", // Warn when numerics are widened.
"-Ywarn-unused:implicits", // Warn if an implicit parameter is unused.
"-Ywarn-unused:imports", // Warn if an import selector is not referenced.
"-Ywarn-unused:locals", // Warn if a local definition is unused.
"-Ywarn-unused:params", // Warn if a value parameter is unused.
"-Ywarn-unused:patvars", // Warn if a variable bound in a pattern is unused.
"-Ywarn-unused:privates", // Warn if a private member is unused.
"-Ywarn-value-discard" // Warn when non-Unit expression results are unused.
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment