Skip to content

Instantly share code, notes, and snippets.

@LukaJCB
LukaJCB / Rank-N-Bifunctors.md
Created September 8, 2019 19:11
Bifunctor extensions

Uniting the bifunctor and monofunctor hierarchies

With the rise of so-called bifunctor IO types, such as ZIO, questions have naturally arisen of how one could leverage the cats-effect type classes to make use of this new power. So far suggestions have mostly focused on duplicating the existing hierarchy into two distinct branches, one parameterized over F[_] and another parameterized over F[_, _]. To me this is not a great situation, as now library maintainers would have to write code for both of these hierarchies or choose one and leave the other one in the dust.

Instead we should find a way to unite the two shapes under a single hierarchy. This is a draft on how to enable this unification using polymorphic function types in Dotty.

@LukaJCB
LukaJCB / UnionMonoidal.scala
Created September 1, 2019 17:26
Union monoidal functors
trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}
trait UnionMonoidal[F[_]] extends Functor[F] {
def union[A, B](fa: F[A], fb: F[B]): F[A | B]
def empty[A]: F[A]
def combineK[A](x: F[A], y: F[A]): F[A] = union(x, y)
def sum[A, B](fa: F[A], fb: F[B]): F[Either[A, B]] =
combineK(map(fa)(Left(_)), map(fb)(Right(_)))
@LukaJCB
LukaJCB / GenMonoid.scala
Created September 1, 2019 15:43
Generalized Monoids
trait Op[A] {
def apply(x: A, y: A): A
}
class Multiply extends Op[Int] {
def apply(x: Int, y: Int) = x * y
}
trait Semigroup[A, O <: Op[A]]
@LukaJCB
LukaJCB / Server.scala
Created December 12, 2018 09:29
Miniserver
package org.typelevel.miniserver
import cats.effect.{ExitCode, IO, IOApp}
import cats.implicits._
import org.http4s.HttpRoutes
import org.http4s.dsl.io._
import org.http4s.implicits._
import org.http4s.circe.CirceEntityEncoder._
import org.http4s.server.blaze.BlazeServerBuilder
import doobie.util.transactor.Transactor
@LukaJCB
LukaJCB / FiberDistributivity.scala
Created November 6, 2018 12:35
Fiber Alternative distributivity
import cats._
import cats.effect._
import scala.concurrent.duration._
import cats.implicits._
import scala.language.higherKinds
implicit val ctx =
IO.contextShift(scala.concurrent.ExecutionContext.global)
implicit val timer =
@LukaJCB
LukaJCB / Semringal.scala
Last active October 26, 2018 22:32
Semiringal Functors
package algebraic
import simulacrum._
import Semiringal.ops._
@typeclass
trait Semigroup[A] {
def combine(x: A, y: A): A
}
@LukaJCB
LukaJCB / MonadTrans.scala
Last active June 29, 2018 14:52
Easy monad transformer lifting?
trait MonadTrans[T[_[_], _]] {
def lift[M[_]: Monad, A](ma: M[A]): T[M, A]
def hoist[M[_]: Monad, N[_]: Monad, A](tma: T[M, A])(f: M ~> N): T[N, A]
}
object MonadTrans {
def apply[T[_[_], _]: MonadTrans]: MonadTrans[T] = implicitly
}
implicit def applicativeAskMonadTrans[T[_[_], _]: MonadTrans, M[_]: Monad, R]
@LukaJCB
LukaJCB / TaglessOptimize.scala
Last active May 3, 2019 10:43
Optimize an Applicative Program with Tagless Final
trait KVStore[F[_]] {
def get(key: String): F[Option[String]]
def put(key: String, a: String): F[Unit]
}
class TestInterpreter() extends KVStore[IO] {
def get(key: String): IO[Option[String]] = IO {
println("Hit network!")
Option(key + "!")
@LukaJCB
LukaJCB / Traverse.scala
Created November 29, 2017 16:20
Traverse
@typeclass trait Semigroup[A] {
def combine(x: A, y: A): A
}
@typeclass trait Monoid[A] extends Semigroup[A] {
def id: A
}
@typeclass trait Semigroupal[F[_]] {
def product[A, B](ga: F[A], gb: F[B]): F[(A, B)]
@LukaJCB
LukaJCB / Algebra.purs
Last active September 22, 2019 13:01
Alternative Tagless Final encoding in PureScript
module Algebra where
import Prelude
import Control.Monad.Eff (Eff)
import Data.Maybe (Maybe(..))
newtype ConsoleAlg f = ConsoleAlg
{ printLn :: String -> f Unit
, readLn :: f String