Last active
May 1, 2016 12:03
-
-
Save gneuvill/a4a75ef89b04651c0378 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// given... | |
class Person { | |
final String name; | |
final Integer age; | |
final Date birth; | |
Person(String name, Integer age, Date birth) { | |
this.name = name; | |
this.age = age; | |
this.birth = birth; | |
} | |
} | |
Maybe<String> getName(String id) { | |
return id.equals("toto") ? Just("Toto Titi") : Nothing(); | |
} | |
Maybe<Integer> getAge(String id) { | |
return id.equals("toto") ? Just(36) : Nothing(); | |
} | |
Maybe<Date> getBirthDate(String name, Integer age) { | |
return name.equals("Toto Titi") && age < 40 ? Just(new Date()) : Nothing(); | |
} | |
// ...we can express | |
// Monadic Do | |
Maybe<Person> maybePers = Do | |
.$(Maybe.instances, Maybe::narrow | |
, () -> getName("toto") | |
, __ -> getAge("toto") | |
, (name, age) -> getBirthDate(name, age) | |
, Person::new); | |
// Interleaved Dos | |
Maybe<Person> maybePers2 = Do | |
.$(Maybe.instances, Maybe::narrow | |
, () -> getName("toto") | |
, __ -> getAge("toto") | |
, (name, age) -> Do | |
.$(Maybe.instances, Maybe::narrow | |
, () -> getBirthDate(name, age) | |
, bd -> new Person(name, age, bd)) // interleaved Dos... | |
, (String __, Integer ___, Person p) -> p); // ... need some help | |
// A test on Eithers created on the fly ; type inference seems to cope with it... | |
Either<String, Person> personOrError = Do | |
.$(Either.instances(), Either::narrow | |
, () -> getName("toto").toEither(() -> "error getting name") | |
, __ -> getAge("toto").toEither(() -> "error getting age") | |
, (name, age) -> getBirthDate(name, age).toEither(() -> "error getting birth date") | |
, Person::new); | |
// applicative Do | |
Maybe<Person> apMaybePers = ApDo. | |
$(Maybe.instances, Maybe::narrow | |
, getName("toto") | |
, getAge("toto") | |
, Just(new Date()) | |
, Person::new); | |
// Traversing on... | |
List<Maybe<String>> maybes = | |
Cons(Just("a"), Cons(Just("b"), Cons(Just("c"), Nil()))); | |
// ... the nice way | |
Maybe<List<String>> listMaybe1 = List.sequenceMaybe(maybes); | |
// ... the less nice (but possible, just in case the short cut isn't available) way | |
Maybe<List<String>> listMaybe2 = | |
Maybe.narrow(List.instances.sequence(List::narrow, Maybe.instances, maybes)); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I've also come up with a poor man's do notation. But I think it still has some security problems. Your input could be valuable.
see: highj/highj#13