Skip to content

Instantly share code, notes, and snippets.

View chenharryhua's full-sized avatar

Harry Chen chenharryhua

  • Tabcorp
  • Melbourne Australia
View GitHub Profile
import fs2.{Chunk, Pull, Stream}
import cats.implicits._
def intersperseN[F[_], A](s: Stream[F, A], separator: A, n: Int): Stream[F, A] = {
def go(ss: Stream[F, A], ck: Chunk[A]): Pull[F, A, Unit] =
ss.pull.uncons.flatMap {
case Some((hl, tl)) =>
val im = (ck.toList ++ hl.toList).grouped(n).toList
val (h, t) = im.splitAt(im.size - 1)
h.traverse(l => Pull.output(Chunk.seq(l :+ separator))) >> go(tl, Chunk.seq(t.flatten))
// https://arxiv.org/pdf/1703.10857.pdf
import cats.Functor
sealed trait FunList[A, B, T] {
def map[U](f: T => U): FunList[A, B, U] = this match {
case Done(t) => Done(f(t))
case More(a, fl) =>
val yoneda: (B => T) => (B => U) = bt => (b => f(bt(b)))
More(a, fl.map(yoneda))
}
@chenharryhua
chenharryhua / fs2 queue.scala
Last active March 3, 2019 03:18
using caffeine cache's RemovalListener as source
implicit val timer = IO.timer(global)
implicit val cs = IO.contextShift(global)
class MyListener(q: Queue[IO, Entry[String]]) extends RemovalListener[String, Entry[String]] {
def onRemoval(key: String, value: Entry[String], cause: RemovalCause): Unit = {
println(s"$key ${cause}")
q.enqueue1(value).unsafeRunSync()
}
}
import scala.compat.java8.FutureConverters
import java.util.concurrent.{CompletableFuture, Future => JFuture}
import java.util.function.Supplier
def lift[F[_]: LiftIO: Sync, A](jf: JFuture[A]): F[A] =
Sync[F].delay(LiftIO[F].liftIO(IO.fromFuture(IO{
FutureConverters.toScala[A](CompletableFuture.supplyAsync(() => jf.get))
})))
.flatten
import cats.data.ContT
import cats.effect.IO
import org.scalatest.FunSuite
import scala.util.continuations._
/**
* scala continuation plugin is equivalent to cats ContT
*/
class ContinuationsTest extends FunSuite {
import cats.{Functor, Monad}
/**
* right kan extension of H along G
* http://comonad.com/reader/2008/kan-extensions/
*/
trait Ran[G[_], H[_], A] {
def apply[B](f: A => G[B]): H[B]
}
import cats.{Applicative, Eval, Functor, Traverse}
sealed trait Base[A]
final case class Child1[A]() extends Base[A]
final case class Child2[A](a: A) extends Base[A]
final case class Child3[A](o: Int => Option[A]) extends Base[A]
object DeriveTraverse extends App {
import cats.implicits._
implicit val functorBase: Functor[Base] = cats.derived.semi.functor[Base]
@chenharryhua
chenharryhua / cat.free-droste.coattr.iso.scala
Last active November 30, 2018 23:08
using monocle to build iso betwee Coattr[F,A] and Free[F,A]
import cats.Functor
import cats.free.Free
import monocle.Iso
import qq.droste.data.Coattr
import qq.droste.data.CoattrImplicits
trait FreeCoattrIso extends CoattrImplicits {
def iso[F[_], A](implicit F: Functor[F]): Iso[Free[F, A], Coattr[F, A]] =
Iso[Free[F, A], Coattr[F, A]] { f =>
Coattr(f.fold[Either[A, F[Coattr[F, A]]]](Left(_), fffa => Right(F.map(fffa)(x => iso.get(x)))))
@chenharryhua
chenharryhua / naive_recursion_scheme.scala
Created November 29, 2018 00:28
Recursion scheme - cata/ana , para/apo, histo/futu
object cata_ana{
val nat: Algebra[Option, Int] = Algebra {
case Some(x) => x
case None => 0
}
val coNat: Coalgebra[Option, Int] = Coalgebra {
(n: Int) => if (n > 0) Some(n - 1) else None
}
scheme.hylo(nat, coNat)
}
@chenharryhua
chenharryhua / recursion schema.scala
Last active November 29, 2018 00:38
recursion scheme - fix[F] and free[F,Nothing] are isomorphic
//https://stackoverflow.com/questions/17307416/difference-between-free-monads-and-fixpoints-of-functors
/**
import Data.Void
import Control.Monad.Free
free2fix :: Functor f => Free f Void -> Fix f
free2fix (Pure void) = absurd void
free2fix (Free body) = Fix (free2fix <$> body)