Skip to content

Instantly share code, notes, and snippets.

Jean-Baptiste Giraudeau jbgi

Block or report user

Report or block jbgi

Hide content and notifications from this user.

Learn more about blocking users

Contact Support about this user’s behavior.

Learn more about reporting abuse

Report abuse
View GitHub Profile
jbgi /
Created Oct 8, 2018
Derive4J for extensible algebraic data types.
interface Exp {
interface ExpAlg<E, R> {
R Lit(int lit);
R Add(E e1, E e2);
<R> R accept(ExpAlg<Exp, R> alg);
jbgi / Option.scala
Created Sep 25, 2018
Zero-cost, subtyping-free conversion from product type to sum type
View Option.scala
sealed trait Option[A]
sealed abstract case class Some[A](value: A) extends Option[A]
sealed abstract case class None[A]() extends Option[A]
sealed trait Id[A] { self: Option[A] =>
final def toOption: Option[A] = this
def value: A
jbgi /
Last active Jun 18, 2018
Why I love parametricity

I try to write code that is "maximally polymorphic" to the extent that I am sufficiently familiar with the concepts involved and that I am confident of being able to efficiently explain my code to co-workers if needed.

I started to use generics in Java to improve reuse of the libraries I wrote at work, but as I was growing a better understanding of types, parametricity and theorems for free, other compelling reasons became prominent:

  1. the free theorems help me reason about code: given parametricity, I know what a function can do and cannot do, based only on its type signature. Eg. given an unconstrained type variable, any value of this type that appears in positive position (output)
jbgi /
Created Oct 15, 2017
Using existentials to implement abstract type alias in Java
import java.util.Arrays;
import java.util.List;
interface Person {
int age();
interface People<T> {
T fromList(List<Person> ps);
jbgi /
Last active May 7, 2017
Automatic derivation of FJ Equal/Hash/Show/Ord "type classes" via derive4j processor-api
import fj.Equal;
import fj.Hash;
import fj.Ord;
import fj.Show;
import java.util.function.Function;
import org.derive4j.Data;
import org.derive4j.Derive;
import org.derive4j.Instances;
@Data(@Derive(@Instances({ Show.class, Hash.class, Equal.class, Ord.class})))
jbgi / ClosestSolutionFound.scala
Last active Apr 25, 2017
How to pattern match with implicit conversion?
View ClosestSolutionFound.scala
trait A {
def toB: B
object A {
def unapply(arg: A): B = arg.toB
sealed trait B {
def isEmpty: Boolean = false
def get: B = this
public abstract class Label<T> {
private Label(){}
public abstract T apply(String s);
public abstract String unwrap(T lbl);
public abstract <f> __<f, String> subst(__<f, T> fa);
jbgi / FileSinks.scala
Last active Dec 16, 2016
"Atomic" file sink through temporary file sink + renaming
View FileSinks.scala
import java.nio.file._
import java.util.concurrent.Executor
import akka.Done
import{FileIO, Sink}
import akka.util.ByteString
import scala.concurrent.{ExecutionContext, Future}
import scala.util.Try
jbgi / Either.scala
Last active Apr 21, 2017
Minimal Either sum type in Scala
View Either.scala
sealed trait Either[A, B]
final case class Left[A, B](a: A) extends Either[A, B]
final case class Right[A, B](b: B) extends Either[A, B]
object Either {
def left[A, B](a: A): Either[A, B] = Left(a)
def right[A, B](b: B): Either[A, B] = Right(b)
jbgi /
Last active Feb 9, 2017
Minimal Either in Java with Derive4J
import java.util.function.Function;
import org.derive4j.Data;
interface Either<A, B> {
<X> X match(Function<A, X> left, Function<B, X> right);
static void main(String[] args) {
You can’t perform that action at this time.