Skip to content

Instantly share code, notes, and snippets.

@SystemFw
SystemFw / Logging.scala
Last active July 13, 2017 13:22
Logging failures on Task
import scalaz.{-\/, \/-}
import scalaz.concurrent.Task
import scalaz.syntax.monad._
/*
* Easily adaptable to Monix, cats, fs2, cats-effect and so on
*/
object Logger {
sealed trait Level
object Level {
@SystemFw
SystemFw / FT.scala
Created August 7, 2017 13:51
[DRAFT] Layered algebras in Free and Final Tagless
object FT {
import cats._, implicits._
trait MoveV[F[_]] {
def up(c: Int): F[Int]
def down(c: Int): F[Int]
}
object MoveV {
implicit def interpreter: MoveV[Id] = new MoveV[Id] {
def up(c: Int) = c + 1
@SystemFw
SystemFw / Diff.scala
Last active August 14, 2017 23:19
Shapeless: update some fields of a class with a Diff, generically
import shapeless._, labelled._, ops.hlist._
object Update extends Poly2 {
implicit def all[A, B, R1 <: HList, R2 <: HList](
implicit oldGen: LabelledGeneric.Aux[A, R1],
newGen: LabelledGeneric.Aux[B, R2],
z: ZipWith.Aux[R1, R2, Update.type, R1]) =
at[A, B] { (old, maybeNew) =>
val oldRepr = oldGen.to(old)
val newRepr = newGen.to(maybeNew)
@SystemFw
SystemFw / semiauto.scala
Created July 13, 2017 13:15
Shapeless semiautomatic derivation
object Module {
import shapeless._
sealed trait Decode[A] {
def decode(s: String): Option[A]
}
object Decode {
def dummy[A]: Decode[A] = new Decode[A] {
def decode(s: String) = Option.empty[A]
}
@SystemFw
SystemFw / Q.scala
Created October 9, 2017 23:20
Shapeless: create an HList of functions from case class T to each of its fields
object Q {
import shapeless._, labelled._, ops.record.Selector
trait Accessors[T, I] {
type Out
def value: Out
}
object Accessors {
type Aux[T, I, O] = Accessors[T, I] { type Out = O }
@SystemFw
SystemFw / Test.scala
Last active July 9, 2018 08:38
Parallel foldMonoid with fs2
object Test {
import cats.implicits._
import cats.kernel.CommutativeMonoid
import cats.effect._
import fs2._
import scala.concurrent.ExecutionContext
// same as parallelFoldMonoid, but with some logging to show the parallelism
def loggedParallelFoldMonoid[F[_], A: CommutativeMonoid](n: Int)(
input: Stream[F, A])(implicit F: Effect[F], ec: ExecutionContext) =
@SystemFw
SystemFw / text.txt
Last active July 23, 2018 18:39
[DRAFT] Free vs Final tagless
So, Free vs Final Tagless.
The first consideration is that the reason why Free is so popular in
Scala, is that Final Tagless didn't quite work (due to ambiguous
implicits), in the current, subtype based encoding of typeclasses used
by cats and scalaz, whereas Free did. However, both libraries are now
addressing the problem, and will accommodate final tagless (also known
as finally tagless, tagless final, mtl style) better. Another
important point is that they are roughly equivalent in power, but some
things might be easier or harder with one of them than with the other.
The thing with Free is: you are reifying a monadic computation into a
@SystemFw
SystemFw / groupBy.scala
Created July 9, 2018 10:32
fs2 `groupBy/partitions`
// Grows with the number of distinct `K`
def partitions[F[_], A, K](selector: A => F[K])(implicit F: Effect[F], ec: ExecutionContext) : Pipe[F, A, (K, Stream[F, A])] = in =>
Stream.eval(async.refOf[F, Map[K, Queue[F, Option[A]]]](Map.empty)).flatMap { st =>
val cleanup = {
import alleycats.std.all._
st.get.flatMap(_.traverse_(_.enqueue1(None)))
}
(in ++ Stream.eval_(cleanup)).evalMap { el =>
(selector(el), st.get).mapN { (key, queues) =>
@SystemFw
SystemFw / Ex.scala
Last active November 3, 2018 17:41
Encoding existentials via abstract types (1) and higher-ranks (2)
// This is the traditional encoding, using abstract type members
// to encode existentials
object AbstractExistentials {
trait E {
type X
val x: X
def f(p: X): String
}
@SystemFw
SystemFw / RankN shift-and-shiftback.md
Last active June 1, 2019 03:15
Cats-effect, blocking, RankN-types.

cats-effect

The cats-effect project defines a purely functional effect type (IO[A]), and associated typeclasses defining its behaviour. The ones we care about for this example are:

trait Sync[F[_]] extends MonadError[F, Throwable] {
   def delay[A](a: => A): F[A]
   ...
}