From 3e4629d873d34ac6c7d54e7e69de48eeea614047 Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Mon, 16 Jul 2018 19:07:19 +0100 Subject: [PATCH] README.org: reformat and adjust headers --- README.org | 713 +++++++++++++++++++++++++++-------------------------- 1 file changed, 369 insertions(+), 344 deletions(-) diff --git a/README.org b/README.org index c882f76..b2ec557 100644 --- a/README.org +++ b/README.org @@ -1,7 +1,4 @@ * Mon - :PROPERTIES: - :CUSTOM_ID: mon - :END: ** TypeAlias, Maybe and Result for Java. @@ -23,10 +20,8 @@ [[https://app.codacy.com/project/kemitix/mon/dashboard][file:https://img.shields.io/codacy/grade/d57096b0639d496aba9a7e43e7cf5b4c.svg?style=for-the-badge]] [[http://i.jpeek.org/net.kemitix/mon/index.html][file:http://i.jpeek.org/net.kemitix/mon/badge.svg]] + ** Maven - :PROPERTIES: - :CUSTOM_ID: maven - :END: #+BEGIN_SRC xml @@ -41,9 +36,6 @@ ** TypeAlias - :PROPERTIES: - :CUSTOM_ID: typealias - :END: In Haskell it is possible to create an alias for a Type, and to then use that alias with the same behaviour as the original, except that the compiler @@ -127,10 +119,8 @@ } #+END_SRC + ** Maybe - :PROPERTIES: - :CUSTOM_ID: maybe - :END: Allows specifying that a value may or may not be present. Similar to =Optional=. =Maybe= provides additional methods that =Optional= doesn't: @@ -180,218 +170,232 @@ =nothing= drops straight through the map and triggers the Runnable parameter in the =match= call. -**** =Maybe= is a Monad: +*** =Maybe= is a Monad: - #+BEGIN_SRC java - package net.kemitix.mon; + #+BEGIN_SRC java + package net.kemitix.mon; - import net.kemitix.mon.maybe.Maybe; - import org.assertj.core.api.WithAssertions; - import org.junit.Test; + import net.kemitix.mon.maybe.Maybe; + import org.assertj.core.api.WithAssertions; + import org.junit.Test; - import java.util.function.Function; + import java.util.function.Function; - public class MaybeMonadTest implements WithAssertions { + public class MaybeMonadTest implements WithAssertions { - private final int v = 1; - private final Function> f = i -> m(i * 2); - private final Function> g = i -> m(i + 6); + private final int v = 1; + private final Function> f = i -> m(i * 2); + private final Function> g = i -> m(i + 6); - private static Maybe m(int value) { - return Maybe.maybe(value); - } + private static Maybe m(int value) { + return Maybe.maybe(value); + } - @Test - public void leftIdentity() { - assertThat( - m(v).flatMap(f) - ).isEqualTo( - f.apply(v) - ); - } + @Test + public void leftIdentity() { + assertThat( + m(v).flatMap(f) + ).isEqualTo( + f.apply(v) + ); + } - @Test - public void rightIdentity() { - assertThat( - m(v).flatMap(x -> m(x)) - ).isEqualTo( - m(v) - ); - } + @Test + public void rightIdentity() { + assertThat( + m(v).flatMap(x -> m(x)) + ).isEqualTo( + m(v) + ); + } - @Test - public void associativity() { - assertThat( - m(v).flatMap(f).flatMap(g) - ).isEqualTo( - m(v).flatMap(x -> f.apply(x).flatMap(g)) - ); - } + @Test + public void associativity() { + assertThat( + m(v).flatMap(f).flatMap(g) + ).isEqualTo( + m(v).flatMap(x -> f.apply(x).flatMap(g)) + ); + } - } - #+END_SRC + } + #+END_SRC -**** Static Constructors -***** =static Maybe maybe(T value)= +*** Static Constructors - Create a Maybe for the value that may or may not be present. +**** =static Maybe maybe(T value)= - Where the value is =null=, that is taken as not being present. + Create a Maybe for the value that may or may not be present. - #+BEGIN_SRC java - final Maybe just = Maybe.maybe(1); - final Maybe nothing = Maybe.maybe(null); - #+END_SRC + Where the value is =null=, that is taken as not being present. -***** =static Maybe just(T value)= + #+BEGIN_SRC java + final Maybe just = Maybe.maybe(1); + final Maybe nothing = Maybe.maybe(null); + #+END_SRC - Create a Maybe for the value that is present. - The =value= must not be =null= or a =NullPointerException= will be thrown. - If you can't prove that the value won't be =null= you should use - =Maybe.maybe(value)= instead. +**** =static Maybe just(T value)= - #+BEGIN_SRC java - final Maybe just = Maybe.just(1); - #+END_SRC + Create a Maybe for the value that is present. -***** =static Maybe nothing()= + The =value= must not be =null= or a =NullPointerException= will be thrown. + If you can't prove that the value won't be =null= you should use + =Maybe.maybe(value)= instead. - Create a Maybe for a lack of a value. + #+BEGIN_SRC java + final Maybe just = Maybe.just(1); + #+END_SRC - #+BEGIN_SRC java - final Maybe nothing = Maybe.nothing(); - #+END_SRC -**** Instance Methods +**** =static Maybe nothing()= -***** =Maybe filter(Predicate predicate)= + Create a Maybe for a lack of a value. - Filter a Maybe by the predicate, replacing with Nothing when it fails. + #+BEGIN_SRC java + final Maybe nothing = Maybe.nothing(); + #+END_SRC - #+BEGIN_SRC java - final Maybe maybe = Maybe.maybe(getValue()) - .filter(v -> v % 2 == 0); - #+END_SRC -***** = Maybe map(Function f)= +*** Instance Methods - Applies the function to the value within the Maybe, returning the result within another Maybe. +**** =Maybe filter(Predicate predicate)= - #+BEGIN_SRC java - final Maybe maybe = Maybe.maybe(getValue()) - .map(v -> v * 100); - #+END_SRC + Filter a Maybe by the predicate, replacing with Nothing when it fails. -***** = Maybe flatMap(Function> f)= + #+BEGIN_SRC java + final Maybe maybe = Maybe.maybe(getValue()) + .filter(v -> v % 2 == 0); + #+END_SRC - Applies the function to the value within the =Maybe=, resulting in another =Maybe=, then flattens the resulting =Maybe>= into =Maybe=. - Monad binder maps the Maybe into another Maybe using the binder method f +**** = Maybe map(Function f)= - #+BEGIN_SRC java - final Maybe maybe = Maybe.maybe(getValue()) - .flatMap(v -> Maybe.maybe(getValueFor(v))); - #+END_SRC + Applies the function to the value within the Maybe, returning the result within another Maybe. -***** =void match(Consumer just, Runnable nothing)= + #+BEGIN_SRC java + final Maybe maybe = Maybe.maybe(getValue()) + .map(v -> v * 100); + #+END_SRC - Matches the Maybe, either just or nothing, and performs either the Consumer, for Just, or Runnable for nothing. - #+BEGIN_SRC java - Maybe.maybe(getValue()) - .match( - just -> workWithValue(just), - () -> nothingToWorkWith() - ); - #+END_SRC +**** = Maybe flatMap(Function> f)= -***** =T orElse(T otherValue)= + Applies the function to the value within the =Maybe=, resulting in another =Maybe=, then flattens the resulting =Maybe>= into =Maybe=. - A value to use when Maybe is Nothing. + Monad binder maps the Maybe into another Maybe using the binder method f - #+BEGIN_SRC java - final Integer value = Maybe.maybe(getValue()) - .orElse(1); - #+END_SRC + #+BEGIN_SRC java + final Maybe maybe = Maybe.maybe(getValue()) + .flatMap(v -> Maybe.maybe(getValueFor(v))); + #+END_SRC -***** =T orElseGet(Supplier otherValueSupplier)= - Provide a value to use when Maybe is Nothing. +**** =void match(Consumer just, Runnable nothing)= - #+BEGIN_SRC java - final Integer value = Maybe.maybe(getValue()) - .orElseGet(() -> getDefaultValue()); - #+END_SRC + Matches the Maybe, either just or nothing, and performs either the Consumer, for Just, or Runnable for nothing. -***** =void orElseThrow(Supplier error)= + #+BEGIN_SRC java + Maybe.maybe(getValue()) + .match( + just -> workWithValue(just), + () -> nothingToWorkWith() + ); + #+END_SRC - Throw the exception if the Maybe is a Nothing. - #+BEGIN_SRC java - final Integer value = Maybe.maybe(getValue()) - .orElseThrow(() -> new RuntimeException("error")); - #+END_SRC +**** =T orElse(T otherValue)= -***** =Maybe peek(Consumer consumer)= + A value to use when Maybe is Nothing. - Provide the value within the Maybe, if it exists, to the Consumer, and returns this Maybe. Conceptually equivalent to the idea of =ifPresent(...)=. + #+BEGIN_SRC java + final Integer value = Maybe.maybe(getValue()) + .orElse(1); + #+END_SRC - #+BEGIN_SRC java - final Maybe maybe = Maybe.maybe(getValue()) - .peek(v -> v.foo()); - #+END_SRC -***** =void ifNothing(Runnable runnable)= +**** =T orElseGet(Supplier otherValueSupplier)= - Run the runnable if the Maybe is a Nothing, otherwise do nothing. + Provide a value to use when Maybe is Nothing. - #+BEGIN_SRC java - Maybe.maybe(getValue()) - .ifNothing(() -> doSomething()); - #+END_SRC + #+BEGIN_SRC java + final Integer value = Maybe.maybe(getValue()) + .orElseGet(() -> getDefaultValue()); + #+END_SRC -***** =Stream stream()= - Converts the Maybe into either a single value stream or an empty stream. +**** =void orElseThrow(Supplier error)= - #+BEGIN_SRC java - final Stream stream = Maybe.maybe(getValue()) - .stream(); - #+END_SRC + Throw the exception if the Maybe is a Nothing. -***** =boolean isJust()= + #+BEGIN_SRC java + final Integer value = Maybe.maybe(getValue()) + .orElseThrow(() -> new RuntimeException("error")); + #+END_SRC - Checks if the Maybe is a Just. - #+BEGIN_SRC java - final boolean isJust = Maybe.maybe(getValue()) - .isJust(); - #+END_SRC +**** =Maybe peek(Consumer consumer)= -***** =boolean isNothing()= + Provide the value within the Maybe, if it exists, to the Consumer, and returns this Maybe. Conceptually equivalent to the idea of =ifPresent(...)=. - Checks if the Maybe is Nothing. + #+BEGIN_SRC java + final Maybe maybe = Maybe.maybe(getValue()) + .peek(v -> v.foo()); + #+END_SRC - #+BEGIN_SRC java - final boolean isNothing = Maybe.maybe(getValue()) - .isNothing(); - #+END_SRC -***** =Optional toOptional()= +**** =void ifNothing(Runnable runnable)= - Convert the Maybe to an Optional. + Run the runnable if the Maybe is a Nothing, otherwise do nothing. + + #+BEGIN_SRC java + Maybe.maybe(getValue()) + .ifNothing(() -> doSomething()); + #+END_SRC + + +**** =Stream stream()= + + Converts the Maybe into either a single value stream or an empty stream. + + #+BEGIN_SRC java + final Stream stream = Maybe.maybe(getValue()) + .stream(); + #+END_SRC + + +**** =boolean isJust()= + + Checks if the Maybe is a Just. + + #+BEGIN_SRC java + final boolean isJust = Maybe.maybe(getValue()) + .isJust(); + #+END_SRC + + +**** =boolean isNothing()= + + Checks if the Maybe is Nothing. + + #+BEGIN_SRC java + final boolean isNothing = Maybe.maybe(getValue()) + .isNothing(); + #+END_SRC + + +**** =Optional toOptional()= + + Convert the Maybe to an Optional. + + #+BEGIN_SRC java + final Optional optional = Maybe.maybe(getValue()) + .toOptional(); + #+END_SRC - #+BEGIN_SRC java - final Optional optional = Maybe.maybe(getValue()) - .toOptional(); - #+END_SRC ** Result - :PROPERTIES: - :CUSTOM_ID: result - :END: Allows handling error conditions without the need to catch exceptions. @@ -443,257 +447,278 @@ Result would have ignored the =flatMap= and skipped to the =match()= when it would have called the error =Consumer=. -**** =Result= is a Monad +*** =Result= is a Monad + + #+BEGIN_SRC java + package net.kemitix.mon; + + import net.kemitix.mon.result.Result; + import org.assertj.core.api.WithAssertions; + import org.junit.Test; + + import java.util.function.Function; + + public class ResultMonadTest implements WithAssertions { + + private final int v = 1; + private final Function> f = i -> r(i * 2); + private final Function> g = i -> r(i + 6); + + private static Result r(int v) { + return Result.ok(v); + } + + @Test + public void leftIdentity() { + assertThat( + r(v).flatMap(f) + ).isEqualTo( + f.apply(v) + ); + } + + @Test + public void rightIdentity() { + assertThat( + r(v).flatMap(x -> r(x)) + ).isEqualTo( + r(v) + ); + } + + @Test + public void associativity() { + assertThat( + r(v).flatMap(f).flatMap(g) + ).isEqualTo( + r(v).flatMap(x -> f.apply(x).flatMap(g)) + ); + } + + } + #+END_SRC + + +*** Static Constructors + +**** =static Result of(Callable callable)= + + Create a Result for a output of the Callable. + + If the Callable throws and Exception, then the Result will be an error and + will contain that exception. + + This will be the main starting point for most Results where the callable + could throw an =Exception=. #+BEGIN_SRC java - package net.kemitix.mon; - - import net.kemitix.mon.result.Result; - import org.assertj.core.api.WithAssertions; - import org.junit.Test; - - import java.util.function.Function; - - public class ResultMonadTest implements WithAssertions { - - private final int v = 1; - private final Function> f = i -> r(i * 2); - private final Function> g = i -> r(i + 6); - - private static Result r(int v) { - return Result.ok(v); - } - - @Test - public void leftIdentity() { - assertThat( - r(v).flatMap(f) - ).isEqualTo( - f.apply(v) - ); - } - - @Test - public void rightIdentity() { - assertThat( - r(v).flatMap(x -> r(x)) - ).isEqualTo( - r(v) - ); - } - - @Test - public void associativity() { - assertThat( - r(v).flatMap(f).flatMap(g) - ).isEqualTo( - r(v).flatMap(x -> f.apply(x).flatMap(g)) - ); - } - - } + final Result okay = Result.of(() -> 1); + final Result error = Result.of(() -> {throw new RuntimeException();}); #+END_SRC -**** Static Constructors -***** =static Result of(Callable callable)= +**** =static Result ok(T value)= - Create a Result for a output of the Callable. + Create a Result for a success. - If the Callable throws and Exception, then the Result will be an error and - will contain that exception. + Use this where you have a value that you want to place into the Result context. - This will be the main starting point for most Results where the callable - could throw an =Exception=. + #+BEGIN_SRC java + final Result okay = Result.ok(1); + #+END_SRC - #+BEGIN_SRC java - final Result okay = Result.of(() -> 1); - final Result error = Result.of(() -> {throw new RuntimeException();}); - #+END_SRC -***** =static Result ok(T value)= +**** =static Result error(Throwable error)= - Create a Result for a success. + Create a Result for an error. - Use this where you have a value that you want to place into the Result context. + #+BEGIN_SRC java + final Result error = Result.error(new RuntimeException()); + #+END_SRC - #+BEGIN_SRC java - final Result okay = Result.ok(1); - #+END_SRC -***** =static Result error(Throwable error)= +*** Static Methods - Create a Result for an error. + These static methods provide integration with the =Maybe= class. - #+BEGIN_SRC java - final Result error = Result.error(new RuntimeException()); - #+END_SRC + #+BEGIN_SRC java + #+END_SRC -**** Static Methods +**** =static Maybe toMaybe(Result result)= - These static methods provide integration with the =Maybe= class. + Creates a =Maybe= from the =Result=, where the =Result= is a success, then + the =Maybe= will contain the value. However, if the =Result= is an error + then the =Maybe= will be nothing. - #+BEGIN_SRC java - #+END_SRC + #+BEGIN_SRC java + final Result result = Result.of(() -> getValue()); + final Maybe maybe = Result.toMaybe(result); + #+END_SRC -***** =static Maybe toMaybe(Result result)= - Creates a =Maybe= from the =Result=, where the =Result= is a success, then - the =Maybe= will contain the value. However, if the =Result= is an error - then the =Maybe= will be nothing. +**** =static Result fromMaybe(Maybe maybe, Supplier error)= - #+BEGIN_SRC java - final Result result = Result.of(() -> getValue()); - final Maybe maybe = Result.toMaybe(result); - #+END_SRC + Creates a =Result= from the =Maybe=, where the =Result= will be an error + if the =Maybe= is nothing. Where the =Maybe= is nothing, then the + =Supplier= will provide the error for the =Result=. -***** =static Result fromMaybe(Maybe maybe, Supplier error)= + #+BEGIN_SRC java + final Maybe maybe = Maybe.maybe(getValue()); + final Result result = Result.fromMaybe(maybe, () -> new NoSuchFileException("filename")); + #+END_SRC - Creates a =Result= from the =Maybe=, where the =Result= will be an error - if the =Maybe= is nothing. Where the =Maybe= is nothing, then the - =Supplier= will provide the error for the =Result=. - #+BEGIN_SRC java - final Maybe maybe = Maybe.maybe(getValue()); - final Result result = Result.fromMaybe(maybe, () -> new NoSuchFileException("filename")); - #+END_SRC +**** =static Result> invert(Maybe> maybeResult)= -***** =static Result> invert(Maybe> maybeResult)= + Swaps the =Result= within a =Maybe=, so that =Result= contains a =Maybe=. - Swaps the =Result= within a =Maybe=, so that =Result= contains a =Maybe=. + #+BEGIN_SRC java + final Maybe> maybe = Maybe.maybe(Result.of(() -> getValue())); + final Result> result = Result.invert(maybe); + #+END_SRC - #+BEGIN_SRC java - final Maybe> maybe = Maybe.maybe(Result.of(() -> getValue())); - final Result> result = Result.invert(maybe); - #+END_SRC -***** =static Result> flatMapMaybe(Result> maybeResult, Function,Result>> f)= +**** =static Result> flatMapMaybe(Result> maybeResult, Function,Result>> f)= - Applies the function to the contents of a Maybe within the Result. + Applies the function to the contents of a Maybe within the Result. - #+BEGIN_SRC java - final Result> result = Result.of(() -> Maybe.maybe(getValue())); - final Result> maybeResult = Result.flatMapMaybe(result, maybe -> Result.of(() -> maybe.map(v -> v * 2))); - #+END_SRC + #+BEGIN_SRC java + final Result> result = Result.of(() -> Maybe.maybe(getValue())); + final Result> maybeResult = Result.flatMapMaybe(result, maybe -> Result.of(() -> maybe.map(v -> v * 2))); + #+END_SRC -**** Instance Methods -***** Result map(Function f) +*** Instance Methods - Applies the function to the value within the Functor, returning the result - within a Functor. +**** = Result map(Function f)= - #+BEGIN_SRC java - final Result result = Result.of(() -> getValue()) - .map(v -> String.valueOf(v)); - #+END_SRC + Applies the function to the value within the Functor, returning the result + within a Functor. -***** Result flatMap(Function> f) + #+BEGIN_SRC java + final Result result = Result.of(() -> getValue()) + .map(v -> String.valueOf(v)); + #+END_SRC - Returns a new Result consisting of the result of applying the function to - the contents of the Result. - #+BEGIN_SRC java - final Result result = Result.of(() -> getValue()) - .flatMap(v -> Result.of(() -> String.valueOf(v))); - #+END_SRC +**** = Result flatMap(Function> f)= -***** Result andThen(Function> f) + Returns a new Result consisting of the result of applying the function to + the contents of the Result. - Maps a Success Result to another Result using a Callable that is able to - throw a checked exception. + #+BEGIN_SRC java + final Result result = Result.of(() -> getValue()) + .flatMap(v -> Result.of(() -> String.valueOf(v))); + #+END_SRC - #+BEGIN_SRC java - final Result result = Result.of(() -> getValue()) - .andThen(v -> () -> {throw new IOException();}); - #+END_SRC -***** void match(Consumer onSuccess, Consumer onError) +**** = Result andThen(Function> f)= - Matches the Result, either success or error, and supplies the appropriate - Consumer with the value or error. + Maps a Success Result to another Result using a Callable that is able to + throw a checked exception. - #+BEGIN_SRC java - Result.of(() -> getValue()) - .match( - success -> System.out.println(success), - error -> System.err.println("error") - ); - #+END_SRC + #+BEGIN_SRC java + final Result result = Result.of(() -> getValue()) + .andThen(v -> () -> {throw new IOException();}); + #+END_SRC -***** Result recover(Function> f) - Provide a way to attempt to recover from an error state. +**** =void match(Consumer onSuccess, Consumer onError)= - #+BEGIN_SRC java + Matches the Result, either success or error, and supplies the appropriate + Consumer with the value or error. + + #+BEGIN_SRC java + Result.of(() -> getValue()) + .match( + success -> System.out.println(success), + error -> System.err.println("error") + ); + #+END_SRC + + +**** =Result recover(Function> f)= + + Provide a way to attempt to recover from an error state. + + #+BEGIN_SRC java + final Result result = Result.of(() -> getValue()) + .recover(e -> Result.of(() -> getSafeValue(e))); + #+END_SRC + + +**** =Result peek(Consumer consumer)= + + Provide the value within the Result, if it is a success, to the Consumer, + and returns this Result. + + #+BEGIN_SRC java + final Result result = Result.of(() -> getValue()) + .peek(v -> System.out.println(v)); + #+END_SRC + + +**** =Result thenWith(Function> f)= + + Perform the continuation with the current Result value then return the + current Result, assuming there was no error in the continuation. + + #+BEGIN_SRC java final Result result = Result.of(() -> getValue()) - .recover(e -> Result.of(() -> getSafeValue(e))); - #+END_SRC + .thenWith(v -> () -> System.out.println(v)) + .thenWith(v -> () -> {throw new IOException();}); + #+END_SRC -***** Result peek(Consumer consumer) - Provide the value within the Result, if it is a success, to the Consumer, - and returns this Result. +**** =Result> maybe(Predicate predicate)= - #+BEGIN_SRC java - final Result result = Result.of(() -> getValue()) - .peek(v -> System.out.println(v)); - #+END_SRC + Wraps the value within the Result in a Maybe, either a Just if the + predicate is true, or Nothing. -***** Result thenWith(Function> f) + #+BEGIN_SRC java + final Result> result = Result.of(() -> getValue()) + .maybe(v -> v % 2 == 0); + #+END_SRC - Perform the continuation with the current Result value then return the - current Result, assuming there was no error in the continuation. - #+BEGIN_SRC java - final Result result = Result.of(() -> getValue()) - .thenWith(v -> () -> System.out.println(v)) - .thenWith(v -> () -> {throw new IOException();}); - #+END_SRC +**** =T orElseThrow()= -***** Result> maybe(Predicate predicate) + Extracts the successful value from the result, or throws the error + Throwable. - Wraps the value within the Result in a Maybe, either a Just if the - predicate is true, or Nothing. + #+BEGIN_SRC java + final Integer result = Result.of(() -> getValue()) + .orElseThrow(); + #+END_SRC - #+BEGIN_SRC java - final Result> result = Result.of(() -> getValue()) - .maybe(v -> v % 2 == 0); - #+END_SRC -***** T orElseThrow() +**** =void onError(Consumer errorConsumer)= - Extracts the successful value from the result, or throws the error - Throwable. + A handler for error states. - #+BEGIN_SRC java - final Integer result = Result.of(() -> getValue()) - .orElseThrow(); - #+END_SRC + #+BEGIN_SRC java + Result.of(() -> getValue()) + .onError(e -> handleError(e)); + #+END_SRC -***** void onError(Consumer errorConsumer) - A handler for error states. +**** =boolean isOkay()= - #+BEGIN_SRC java - Result.of(() -> getValue()) - .onError(e -> handleError(e)); - #+END_SRC + Checks if the Result is a success. -***** boolean isOkay() + #+BEGIN_SRC java + final boolean isOkay = Result.of(() -> getValue()) + .isOkay(); + #+END_SRC - Checks if the Result is a success. - #+BEGIN_SRC java - final boolean isOkay = Result.of(() -> getValue()) - .isOkay(); - #+END_SRC +**** =boolean isError()= -***** boolean isError() + Checks if the Result is an error. + + #+BEGIN_SRC java + final boolean isError = Result.of(() -> getValue()) + .isError(); + #+END_SRC - Checks if the Result is an error. - #+BEGIN_SRC java - final boolean isError = Result.of(() -> getValue()) - .isError(); - #+END_SRC