Skip to content

Instantly share code, notes, and snippets.

View gvolpe's full-sized avatar
🤓
https://leanpub.com/u/gvolpe

Gabriel Volpe gvolpe

🤓
https://leanpub.com/u/gvolpe
View GitHub Profile
@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 February 15, 2024 15:29
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 July 6, 2023 00:19
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 {}
@gvolpe
gvolpe / Ex.scala
Created November 3, 2018 04:43 — forked from SystemFw/Ex.scala
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
}