Skip to content

Instantly share code, notes, and snippets.

View qingwei91's full-sized avatar

Qing qingwei91

View GitHub Profile
@qingwei91
qingwei91 / naive-loop.scala
Created December 20, 2019 14:26
Loop with termination logic built in
def loop(stopsAfter: Duration) = {
val start: Instant = Instant.now()
while (true) {
if (start.after(stopsAfter) < Instant.now()) {
throw new NonTerminatingError()
} else {
// do your thing
}
}
}
@qingwei91
qingwei91 / io-loop.scala
Created December 20, 2019 14:27
Use IO to wrap each loop
import cats.effect._
def retryIfNone(innerIO: IO[Option[Int]]): IO[Int] = {
innerIO.flatMap {
case Some(i) =>
println("something") // used to show some output when testing
IO.pure(i)
case None =>
println("nothing") // used to show some output when testing
retryIfNone(innerIO)
import cats.effect._
import scala.concurrent.ExecutionContext.global
// needed to perform logical fork
implicit val cs = IO.contextShift(global)
// an infinite `flatMap` chain as the innerIO always return None
val myIO = retryIfNone(IO(None))
// perform a logical fork using `.start`, this to allow cancellation
def cancellableLoop[F[_], LoopCtx, A](
step: LoopCtx => Either[LoopCtx, A]
)(init: LoopCtx)(implicit cs: ContextShift[F], monad: Monad[F]): F[A] = {
def inner(in: LoopCtx, i: Int): F[A] = {
if (i > 2000) {
cs.shift.flatMap(_ => inner(in, 0))
} else {
step(in) match {
case Left(cont) => inner(cont, i + 1)
// create non-terminating loop
val cancellable = cancellableLoop[IO, Int, Int](i => {println("a step");Left(i)})(0)
val fiber = cancellable.start.unsafeRunSync
fiber.cancel.unsafeRunSync
@qingwei91
qingwei91 / stream-flattap.scala
Created February 27, 2020 12:36
flatTap is interesting
import $ivy.`org.typelevel::cats-effect:2.1.1`
import $ivy.`co.fs2::fs2-core:2.2.2`
import fs2._
import cats.effect._
import cats.implicits._
val inputStream = Stream.emits[IO, Int](0 to 10)
def sideEffect(i:Int): Stream[IO, Int] = Stream.emits(1 to 3)
#!/usr/bin/env sh
# This is a wrapper script, that automatically download ammonite from GitHub release pages
# You can give the required mill version with AMM_VERSION env variable
# If no version is given, it falls back to the value of DEFAULT_AMM_VERSION
DEFAULT_AMM_VERSION=2.0.4
SCALA_VERSION=2.12
set -e
@qingwei91
qingwei91 / rt.scala
Created December 1, 2022 10:40
referential transparent
/**
A piece of code can be replaced by a variable/function that represent itself, in all cases!
*/
val x = 1 + 2
val y = x + x
val z = (1 + 2) + (1+2)
assert(z == y == (x + x))
var mx = 20
@qingwei91
qingwei91 / io-sample.scala
Last active December 29, 2022 11:38
Sample IO
import cats.effects._
val knockNeighborsDoor = IO(raiseHandAndKnock)
knockNeighborsDoor.unsafeRunSync == noResponse
knockNeighborsDoor.unsafeRunSync == neighborOpenDoor
@qingwei91
qingwei91 / io-high-compose.scala
Last active December 29, 2022 11:56
High level composition of IO
import cats.effect._
val a = IO(...)
val b = IO(...)
a.map(transformA) // transform output of effect
a >> b // a then b, in other words, FlatMap
(a, b).parTupled // a and b concurrently, then use the output