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
jbgi / Exp.java
Created Oct 8, 2018
Derive4J for extensible algebraic data types.
View Exp.java
@Data
interface Exp {
interface ExpAlg<E, R> {
R Lit(int lit);
R Add(E e1, E e2);
}
<R> R accept(ExpAlg<Exp, R> alg);
@jbgi
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
jbgi / Parametricity.md
Last active Jun 18, 2018
Why I love parametricity
View Parametricity.md

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
jbgi / Program.java
Created Oct 15, 2017
Using existentials to implement abstract type alias in Java
View Program.java
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
interface Person {
int age();
}
interface People<T> {
T fromList(List<Person> ps);
@jbgi
jbgi / Either.java
Last active May 7, 2017
Automatic derivation of FJ Equal/Hash/Show/Ord "type classes" via derive4j processor-api
View Either.java
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
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
View Label.java
import java.io.IOException;
import org.derive4j.hkt.__;
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
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 akka.stream.IOResult
import akka.stream.scaladsl.{FileIO, Sink}
import akka.util.ByteString
import scala.concurrent.{ExecutionContext, Future}
import scala.util.Try
@jbgi
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
jbgi / Either.java
Last active Feb 9, 2017
Minimal Either in Java with Derive4J
View Either.java
import java.util.function.Function;
import org.derive4j.Data;
@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.