Skip to content

Instantly share code, notes, and snippets.

View gvolpe's full-sized avatar

Gabriel Volpe gvolpe

View GitHub Profile
// (.) :: (b -> c) -> (a -> b) -> a -> c
implicit class FancyComposition[A, B, C](f: B => C) {
def `.`(g: A => B): A => C = f.compose(g)
}
val f: Int => String = _.toString
val g: String => Boolean = _.contains("1")
val h: Int => Boolean = g `.` f
@gvolpe
gvolpe / gadt.md
Created January 31, 2019 06:40 — forked from smarter/gadt.md
GADTs in Scala

Generalized Algebraic Data Types in Scala

Basic GADTs

Here's an ADT which is not a GADT, in Haskell:

data Expr = IntExpr Int | BoolExpr Bool
@gvolpe
gvolpe / laws.md
Created January 31, 2019 06:30 — forked from non/laws.md
I feel like conversations around laws and lawfulness in Scala are often not productive, due to a lack of rigor involved. I wanted to try to be as clear and specific as possible about my views of lawful (and unlawful) behavior, and what I consider a correct and rigorous way to think about laws (and their limits) in Scala.

Laws

A law is a group of two or more expressions which are required to be the same. The expressions will usually involve one or more typed holes ("inputs") which vary.

Some examples:

x.map(id) === x
@gvolpe
gvolpe / parTraverseN.scala
Last active November 7, 2024 01:47
parTraverse with a limit of N using a Semaphore
import cats.Traverse
import cats.effect._
import cats.effect.concurrent.Semaphore
import cats.temp.par._
import cats.syntax.all._
import scala.concurrent.duration._
object Main extends IOApp {
import ParTask._
import cats.data.Kleisli
import cats.effect.{ Concurrent, Sync }
import cats.effect.concurrent.MVar
import cats.implicits._
import cats.{ Applicative, Functor, Monad }
// Let's start with our dsl
// First we need to interact with a console
trait Console[F[_]] {
@gvolpe
gvolpe / quantified.scala
Created January 12, 2019 01:32 — forked from neko-kai/quantified.scala
Tagless final for ZIO via quantified constraints
package quantified
import cats.Monad
import scala.language.implicitConversions
/** C[_] constraint applied to type F[_, _] quantified in first parameter */
final class Quant[+C[_[_]], F[_, _]] private (private val erased: C[F[Any, ?]]) extends AnyVal {
type State = Defined

Preliminaries

type Void <: Nothing
type ¬[-A] = A => Void
type ¬¬[+A] = ¬[¬[A]]
type [+A, +B] = Either[A, B]
type [+A, +B] = Tuple2[A, B]
@gvolpe
gvolpe / CsvApp.scala
Last active November 13, 2025 17:47
CSV file reader using the Fs2 streaming library.
import cats.effect._
import cats.syntax.functor._
import fs2._
import java.nio.file.Paths
import java.util.concurrent.Executors
import scala.concurrent.ExecutionContext
import scala.util.Try
object CsvApp extends IOApp {
import cats.Id
import polymorphic._
import polymorphic.syntax.all._
// Type mismatch: found b.type, required: A
//def nope[A, B](f: A => List[A], b: B, s: String): (List[B], List[String]) = (f(b), f(s))
// If Scala had Rank-N types it would be defined as:
//def notValid[B](f: (A => List[A]) forAll { A }, b: B, s: String): (List[B], List[String]) = (f(b), f(s))
@gvolpe
gvolpe / existentials-alt.scala
Last active November 3, 2018 06:37
Alternative encoding of https://gist.github.com/gvolpe/fba7efc41e924bb194e6eaabac309a09 using the Polymorphic library
import polymorphic._
import polymorphic.syntax.all._
class Data[A](val x: A, val f: A => String)
trait E {
def f(ex: ∃[Data]): String = ex match { case Exists(d) => d.f(d.x) }
}
val e = new E {}