patternjavaMinor
An Either Monad in Java
Viewed 0 times
eitherjavamonad
Problem
Interested in a review of this code, in particular the (hopefully monadic) bind. I actually put this to good use. It was a nice complement to Guava's Optional, and shorter than:
Optional.fromNullable(x).or(y);
And I threw in a
One question I wasn't sure of the the semantics of multiple calls. Should I carry along the original default value, or does each new value become the default? So in psuedo code, should
Either.with("A").or("B").or(null)
result in "A" (the original default) or "B"? I thought "B" made more sense.
I'm interested in if I got the monad signature & semantics right.
And here are the unit tests for bind (and sample usage):
```
static c
Optional.fromNullable(x).or(y);
And I threw in a
bind method, which I think lifts it up into monad space.One question I wasn't sure of the the semantics of multiple calls. Should I carry along the original default value, or does each new value become the default? So in psuedo code, should
Either.with("A").or("B").or(null)
result in "A" (the original default) or "B"? I thought "B" made more sense.
I'm interested in if I got the monad signature & semantics right.
public class Either {
private final A value;
/**
* constructor sets the default & value the same
* @param defaultValue
*/
Either(A value) {
if (value == null) {
throw new IllegalArgumentException("Either cannot be null");
}
this.value = value;
}
/**
* constructor sets the default & value the same
* @param defaultValue
*/
Either(A defaultValue, A value) {
this.value = (value == null) ? defaultValue : value;
}
/**
* the unit method lifts the value into the monadic space
*
* @param value
* @return an either with the value as default
*/
public static Either with(A value) {
return new Either(value);
}
/**
* create a new either using the previous default
*
* @param value
* @return
*/
public Either or(A value) {
return new Either(this.value, value);
}
/**
* @return the value, or the default
*/
public A get() {
return value;
}
/**
* completes this class as a monad
*
* @param f
* @return an either of the new type
*/
public Either bind(Function> f) {
return f.apply(value);
}
}And here are the unit tests for bind (and sample usage):
```
static c
Solution
I have a nit-pick with the logic in your
but, since
I would write that method:
I know that essentially duplicates the constructor, but, doing it this way avoids the constructor in (hopefully) many places entirely.
This leads on to your question:
One question I wasn't sure of the the semantics of multiple calls.
Should I carry along the original default value, or does each new
value become the default? So in psuedo code, should
result in "A" (the original default) or "B"? I thought "B" made more
sense.
If the
Either.or(A) method. You have:public Either or(A value) {
return new Either(this.value, value);
}but, since
Either is immutable (oh, should Either be a final class? ... I think so...), it makes sense that the or method can return the exact instance if it is valid.... why does it have to create a new instance each time? In a stream that can create a lot of GC churn....I would write that method:
public Either or(A value) {
return value == null ? this : new Either(value);
}I know that essentially duplicates the constructor, but, doing it this way avoids the constructor in (hopefully) many places entirely.
This leads on to your question:
One question I wasn't sure of the the semantics of multiple calls.
Should I carry along the original default value, or does each new
value become the default? So in psuedo code, should
Either.with("A").or("B").or(null)result in "A" (the original default) or "B"? I thought "B" made more
sense.
If the
or(A) method does not need to construct a new instance, then it makes sense to me that the semantics should return "A", since that allows skipping new instances for "B" and null.Code Snippets
public Either<A> or(A value) {
return new Either<A>(this.value, value);
}public Either<A> or(A value) {
return value == null ? this : new Either<A>(value);
}Either.with("A").or("B").or(null)Context
StackExchange Code Review Q#42702, answer score: 8
Revisions (0)
No revisions yet.