Skip to content

Instantly share code, notes, and snippets.

@danieldietrich
Last active August 29, 2015 14:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danieldietrich/700d4a70d764548648e7 to your computer and use it in GitHub Desktop.
Save danieldietrich/700d4a70d764548648e7 to your computer and use it in GitHub Desktop.
Pattern Matching for Java
public static void main(final String... args) {
// this is javaslang.collection.Stream
Stream.of(0, 1, 2, 3, 13, 14, null, -1)
.peek(n -> out.print(format("%d -> ", n)))
.map(Match.as(Object.class) // match as function
.when(Objects::isNull).then("!")
.whenIs(0).then(nil())
.when(is(1)).then("one")
.whenIs(13).then(() -> "unlucky")
.whenIs(14).then(printIt())
.when((Integer i) -> i % 2 == 0).then(i -> i * 3)
.when(gt(2)).then(dec())
.otherwise(() -> "no match"))
.map(MatchingTest::toString)
.forEach(out::println);
out.flush(); // Avoid mixing sout and serr
// match as monad (with map, flatMap, etc.)
Match.of(0).as(Void.class)
// a Match without when makes no sense
.when(ignored -> false).then(() -> null)
.orElseThrow(RuntimeException::new);
}
//
// Example taken from http://binkley.blogspot.ch/2015/06/pattern-matching-for-java.html
//
public static void main(final String... args) {
asList(0, 1, 2, 3, 13, 14, null, -1).stream()
.peek(n -> out.print(format("%d -> ", n))).
.map(matching(Integer.class, Object.class)
.when(Objects::isNull).then(n -> "!")
.when(is(0)).then(nil())
.when(is(1)).then("one")
.when(is(13)).then(() -> "unlucky")
.when(is(14)).then(printIt())
.when(even()).then(scaleBy(3))
.when(gt(2)).then(dec())
.none().then("no match"))
.map(MatchingTest::toString)
.forEach(out::println);
out.flush(); // Avoid mixing sout and serr
matching(Integer.class, Void.class)
.none().thenThrow(RuntimeException::new)
.apply(0);
}
public static void main(final String... args) {
Stream.of(0, 1, 2, 3, 13, 14, null, -1)
.peek(n -> out.print(format("%d -> ", n)))
.map(Match.as(Object.class) // Match function (with apply(Object))
.when(Objects::isNull).then("!")
.whenIs(0).then("zero")
.whenIsIn(1, 13, 14).then(i -> "first digit 1: " + i)
.whenType(Double.class).then(d -> "Found a double: " + d)
.whenApplicable((Number num) -> "number: " + num).thenApply()
.otherwise(() -> "no match"))
.map(MatchingTest::toString)
.forEach(out::println);
out.flush(); // Avoid mixing sout and serr
// Match monad (with map(), flatMap(), get(), orElse(), orElseGet(), orElseThrow(), etc.)
for (String s : Match.of(0)
.whenType(Number.class).then(Object::toString)
.otherwise("unknown")
.map(String::toUpperCase)) {
out.println(s);
}
}
  1. Scala allows to match more special objects by more general cases:
Some(1) match { case o: Option[Int] => true } // = true
  1. Scala also allows to match more general objects by more special cases:
val o: Option[Int] = Some(1)
o match { case Some(1) => true } // = true

Both cases are supported by Javaslang:

Ad 1)

// Match as Monad
Match.of(new Some<>(1))
     .whenApplicable((Option<Integer> i) -> true).thenApply()
     .get(); // = true
     
Match.of(new Some<>(1))
     .whenType(Option.class).then(true)
     .get(); // = true

// Match as Function
Match.whenApplicable((Option<Integer> i) -> true).thenApply()
     .apply(new Some<>(1)); // = true
    
Match.whenType(Option.class).then(true)
     .apply(new Some<>(1)); // = true

Ad 2)

// Match as Monad
Match.of(Option.of(1))
     .whenIs(new Some<>(1)).then(true)
     .get(); // = true

// Match as Function
Match.whenIs(new Some<>(1)).then(true)
     .apply(Option.of(1)); // = true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment