Skip to content

Instantly share code, notes, and snippets.

@Dierk
Created January 20, 2017 09:41
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Dierk/32341c50de6c93c67d067b26a3b8146c to your computer and use it in GitHub Desktop.
Save Dierk/32341c50de6c93c67d067b26a3b8146c to your computer and use it in GitHub Desktop.
Either type in Groovy as a special implementation of the generic sum type (works the same in Java)
// Either type in Groovy as a special implementation of the generic sum type
// see: Phil Wadler at LambdaWorld 2016: youtu.be/V10hzjgoklA
import java.util.function.*
import groovy.transform.*
interface Either<A,B> {
public <C> C match (Function <A,C> leftCase, Function <B,C> rightCase)
}
@Canonical
class Left<A,B> implements Either<A,B> {
final A x
public <C> C match (Function <A,C> leftCase, Function <B,C> rightCase) {
leftCase.apply(x)
}
}
@Canonical
class Right<A,B> implements Either<A,B> {
final B x
public <C> C match (Function <A,C> leftCase, Function <B,C> rightCase) {
rightCase.apply(x)
}
}
Either<String, Number> divide(Number dividend, Number divisor) {
if (0 == divisor) return new Left("Sorry, cannot divide $dividend by 0")
new Right(dividend / divisor)
}
String format(Either<String, Number> either) {
either.match (
{ it }, // left case
{ Number n -> n } // right case
)
}
assert format(divide(84, 0)) == "Sorry, cannot divide 84 by 0"
assert format(divide(84, 2)) == "42" // note the String type!
// now the fun starts
// we can make this a functor, applicative, monad ...
@jbgi
Copy link

jbgi commented Feb 8, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment