Skip to content

Instantly share code, notes, and snippets.

Avatar

Jean-Baptiste Giraudeau jbgi

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.