Skip to content

Instantly share code, notes, and snippets.

View soujiro32167's full-sized avatar
👾
Software is eating the world

Eli Kasik soujiro32167

👾
Software is eating the world
  • Traverse Labs
  • Montreal, QC
View GitHub Profile
@soujiro32167
soujiro32167 / partition.scala
Last active January 28, 2025 23:28
A generic partitioning of a list of enums
//> using scala 3.6.3
import scala.deriving.Mirror
import scala.compiletime.{erasedValue}
/** Type-level function that transforms a type-level tuple of types
* into a corresponding tuple of List[...] at the value level.
*
* E.g., if Ts is (T1, T2, T3), Partitioned[Ts] is (List[T1], List[T2], List[T3]).
*/
@soujiro32167
soujiro32167 / task-manager.scala
Last active August 1, 2024 21:27
Task manager
//> using scala 3
//> using dep "dev.zio::zio:2.1.6"
import zio.*
import zio.internal.FiberRuntime
import java.util.UUID
trait TaskManager {
def add(task: Task[Unit]): UIO[UUID]
def stop(id: UUID): UIO[Unit]
@soujiro32167
soujiro32167 / avro_discriminator.scala
Created February 28, 2023 16:37
When your avro needs a discriminator in the payload
import vulcan.{AvroError, Codec}
import vulcan.generic.*
import zio.{ZIO, ZIOAppDefault}
sealed trait Foo
object Foo {
case class A(a: Int, `type`: "A" = "A") extends Foo
case class B(b: String, `type`: "B" = "B") extends Foo
@soujiro32167
soujiro32167 / pgnotify.scala
Created January 13, 2023 20:19
Doobie postgres listen + notify CDC
import cats.effect.{IO, IOApp, Resource}
import doobie.postgres.PHC
import doobie.{ConnectionIO, HC, LogHandler, Transactor}
import fs2.Pipe
import org.postgresql.PGNotification
import scala.concurrent.duration.*
import cats.syntax.all.*
import doobie.implicits.*
import fs2.Stream
@soujiro32167
soujiro32167 / inline.scala
Created December 4, 2022 19:41
Scala 3: Matching on member of a union types
inline def f2[A, B](x: A | B): String =
x match
case a: A => "a"
case b: B => "b"
// doesn't work with subtyping
trait T[A] {
def foo(a: A): String
}
@soujiro32167
soujiro32167 / producer.scala
Created December 2, 2022 21:21
Multi-topic sealed trait kafka producer
import _root_.vulcan.Codec
import _root_.vulcan.generic.*
import foo.Events.{E1, E2}
import fs2.kafka.*
import fs2.kafka.vulcan.{AvroSettings, SchemaRegistryClientSettings, avroSerializer}
import zio.interop.catz.*
import zio.interop.catz.implicits.rts
import zio.{Scope, Task, ZIO, ZIOAppDefault}
object foo extends ZIOAppDefault {
@soujiro32167
soujiro32167 / newtypes.amm
Created October 3, 2022 14:02
Deriving typeclasses for zio-prelude newtypes outside of the object scope (scala2 only)
import $ivy.`dev.zio::zio-prelude:1.0.0-RC15`
import zio.prelude.Newtype
object newtypes {
def derive[A, STA <: Newtype[A], F[_]](implicit ev: STA <:< Newtype[A], typeClass: F[A]): F[STA#Type] =
typeClass.asInstanceOf[F[STA#Type]]
trait Auto {
implicit def auto[A, STA <: Newtype[A], F[_]](implicit ev: STA <:< Newtype[A], typeClass: F[A]): F[STA#Type] =
@soujiro32167
soujiro32167 / unioncompose.scala
Created October 3, 2022 13:33
Composing effects with union types
trait F[+A]{
def ++[B >: A](that: F[B]): F[B]
def flatMap[B >: A](f: A => F[B]): F[B]
def map[B](f: A => B): F[B]
}
trait A
trait B
trait C
@soujiro32167
soujiro32167 / flateither.scala
Created October 3, 2022 13:31
Flattening an Either tree in Scala 3
import scala.annotation.tailrec
type FlatEither[A] = A match
case Either[l, r] => FlatEither[l] | FlatEither[r]
case _ => A
@tailrec
def flatEither[A](a: A): FlatEither[A] = a match
case e: Either[?, ?] => e match
case Right(r) => flatEither(r)
@soujiro32167
soujiro32167 / bug.scala
Created October 30, 2021 19:41
Tapir ZIO Http composition bug
import sttp.client3.asynchttpclient.zio.{AsyncHttpClientZioBackend, SttpClient}
import sttp.tapir.server.ziohttp.ZioHttpInterpreter
import zhttp.http.RHttpApp
import zhttp.service.{EventLoopGroup, Server}
import zhttp.service.server.ServerChannelFactory
import zio.{Runtime, ZIO}
object tapir {
import sttp.tapir.ztapir._