Skip to content

Commit

Permalink
Hardened API regarding #8.
Browse files Browse the repository at this point in the history
Added missing javadoc.
  • Loading branch information
danieldietrich committed Aug 21, 2014
1 parent 351af2a commit a6e313c
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 43 deletions.
3 changes: 2 additions & 1 deletion src/main/java/javaslang/match/Applicative.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ interface Applicative<R> {
boolean isApplicable(Object obj);

/**
* Maps a given object to an object of type R.
*
* @param obj An object.
* @return
* @return The mapping result.
*/
R apply(Object obj);
}
19 changes: 17 additions & 2 deletions src/main/java/javaslang/match/Decomposable.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,25 @@
*/
package javaslang.match;

import java.io.Serializable;

import javaslang.Tuples.Tuple;

public interface Decomposable<T, R extends Tuple> {
/**
* An object which implements this interface signals that it is decomposable, i.e. can be decomposed to the parts it is
* composed of.
*
* @param <T> Type of object to be decomposed.
* @param <R> Container type for the parts an object is composed of.
*/
// DEV-NOTE: Serializable & @FunctionalInterface to be compatible with {@link javaslang.Lambdas#getLambdaSignature(Serializable)}
@FunctionalInterface
public interface Decomposable<T, R extends Tuple> extends Serializable {

/**
* Returns a {@link Decomposition} that is able to decompose objects of type T.
*
* @return A Decomposition for object of type T.
*/
Decomposition<T, R> decomposition();

}
29 changes: 28 additions & 1 deletion src/main/java/javaslang/match/Decomposition.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,37 @@
*/
package javaslang.match;

import java.io.Serializable;

import javaslang.Tuples.Tuple;

public interface Decomposition<T, R extends Tuple> {
/**
* Interface for object decomposition, simmilar to Scala's {@code unapply()}. A Tuple serves as container type for the
* parts, an object is composed of.
*
* @param <T> Type of object to be decomposed.
* @param <R> Container type for the parts an object is composed of.
*/
// DEV-NOTE: extending Decomposable reduces interface Pattern by 50%
//DEV-NOTE: Serializable & @FunctionalInterface to be compatible with {@link javaslang.Lambdas#getLambdaSignature(Serializable)}
@FunctionalInterface
public interface Decomposition<T, R extends Tuple> extends Decomposable<T, R>, Serializable {

/**
* Performs the decomposition.
*
* @param t The object to be decomposed.
* @return The tuple containing the parts of the given object t.
*/
R apply(T t);

/**
* Returning this.
*
* @return A Decomposition for object of type T.
*/
@Override
default Decomposition<T, R> decomposition() {
return this;
}
}
121 changes: 82 additions & 39 deletions src/main/java/javaslang/match/Pattern.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,100 +5,143 @@
*/
package javaslang.match;

import static javaslang.Requirements.requireNonNull;
import javaslang.Lambdas;
import javaslang.Lambdas.LambdaSignature;
import javaslang.Tuples;
import javaslang.Tuples.Tuple;
import javaslang.Tuples.Tuple1;
import javaslang.Tuples.Tuple2;
import javaslang.option.Option;

// TODO: Matchs.caze(Pattern.of(decompositionOfA, any(), any()), (a, dA) -> ???)
public interface Pattern<R extends Tuple> extends Applicative<R> {
// TODO: Matchs.caze(Pattern.of(decomposableOfA, any(), any()), (a, dA) -> ???)
public interface Pattern<R extends Tuple> extends Applicative<Option<R>> {

/**
* Creates a Pattern for objects of type T. The Pattern matches a given object o, if {@code isApplicable(o)} returns
* true and {@code prototype.equals(decomposition.apply(o))} returns true.
*
* @param <T> Type of objects to be pattern matched.
* @param <R> Decomposition result.
* @param decomposable A Decomposable which provides a Decomposition for objects of type T.
* @param prototype The Pattern matches, ifA prototype which will be compared
* @return Some(decompositionResult) if the Pattern matches, otherwise None.
*/
@Override
boolean isApplicable(Object o);
static <T, R extends Tuple> Pattern<R> of(Decomposable<T, R> decomposable, R prototype) {

/**
*
* @param o
* @return
*/
@Override
R apply(Object o);
requireNonNull(decomposable, "decomposable is null");
requireNonNull(prototype, "prototype is null");

static <T, R extends Tuple> Pattern<R> of(Decomposition<T, R> decomposition, R prototype) {
return null;
final Decomposition<T, R> decomposition = requireNonNull(decomposable.decomposition(), "decomposition is null");
final LambdaSignature signature = Lambdas.getLambdaSignature(decomposition);

return new Pattern<R>() {
@Override
public boolean isApplicable(Object obj) {
return obj != null && signature.getParameterType(0).isAssignableFrom(obj.getClass());
}

@Override
@SuppressWarnings("unchecked")
public Option<R> apply(Object obj) {
final R components = decomposition.apply((T) obj);
if (prototype.equals(components)) {
return Option.of(components);
} else {
return Option.empty();
}
}
};
}

static <T, E1> Pattern<Tuple1<E1>> of(Decomposition<T, Tuple1<E1>> decomposition, E1 e1) {
return Pattern.of(decomposition, Tuples.of(e1));
/**
* Convenience method for {@code Pattern.of(decomposable, Tuples.of(e1))}.
*
* @param <T> Type of objects to be pattern matched.
* @param <E1> Type of decomposition component 1.
* @param decomposable A Decomposable which provides a {@link Decomposition} of arity 1 for object of type T.
* @param e1 Component 1 of the pattern that will be matched against component 1 of a decomposition.
* @return A Pattern which is applicable to objects of type T.
*/
static <T, E1> Pattern<Tuple1<E1>> of(Decomposable<T, Tuple1<E1>> decomposable, E1 e1) {
return Pattern.of(decomposable, Tuples.of(e1));
}

static <T, E1, E2> Pattern<Tuple2<E1, E2>> of(Decomposition<T, Tuple2<E1, E2>> decomposition, E1 e1, E2 e2) {
return Pattern.of(decomposition, Tuples.of(e1, e2));
/**
* Convenience method for {@code Pattern.of(decomposable, Tuples.of(e1, e2))}.
*
* @param <T> Type of objects to be pattern matched.
* @param <E1> Type of decomposition component 1.
* @param <E2> Type of decomposition component 2.
* @param decomposable A Decomposable which provides a {@link Decomposition} of arity 2 for object of type T.
* @param e1 Component 1 of the pattern that will be matched against component 1 of a decomposition.
* @param e2 Component 2 of the pattern that will be matched against component 2 of a decomposition.
* @return A Pattern which is applicable to objects of type T.
*/
static <T, E1, E2> Pattern<Tuple2<E1, E2>> of(Decomposable<T, Tuple2<E1, E2>> decomposable, E1 e1, E2 e2) {
return Pattern.of(decomposable, Tuples.of(e1, e2));
}

// TODO: commented out because of Eclipse JDT bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=442245">https://bugs.eclipse.org/bugs/show_bug.cgi?id=442245</a>
// static <T, E1, E2, E3> Pattern<Tuple3<E1, E2, E3>> of(Decomposition<T, Tuple3<E1, E2, E3>> decomposition, E1 e1,
// static <T, E1, E2, E3> Pattern<Tuple3<E1, E2, E3>> of(Decomposable<T, Tuple3<E1, E2, E3>> decomposable, E1 e1,
// E2 e2, E3 e3) {
// return Pattern.of(decomposition, Tuples.of(e1, e2, e3));
// return Pattern.of(decomposable, Tuples.of(e1, e2, e3));
// }
//
// static <T, E1, E2, E3, E4> Pattern<Tuple4<E1, E2, E3, E4>> of(
// Decomposition<T, Tuple4<E1, E2, E3, E4>> decomposition, E1 e1, E2 e2, E3 e3, E4 e4) {
// return Pattern.of(decomposition, Tuples.of(e1, e2, e3, e4));
// Decomposable<T, Tuple4<E1, E2, E3, E4>> decomposable, E1 e1, E2 e2, E3 e3, E4 e4) {
// return Pattern.of(decomposable, Tuples.of(e1, e2, e3, e4));
// }
//
// static <T, E1, E2, E3, E4, E5> Pattern<Tuple5<E1, E2, E3, E4, E5>> of(
// Decomposition<T, Tuple5<E1, E2, E3, E4, E5>> decomposition, E1 e1, E2 e2, E3 e3, E4 e4, E5 e5) {
// return Pattern.of(decomposition, Tuples.of(e1, e2, e3, e4, e5));
// Decomposable<T, Tuple5<E1, E2, E3, E4, E5>> decomposable, E1 e1, E2 e2, E3 e3, E4 e4, E5 e5) {
// return Pattern.of(decomposable, Tuples.of(e1, e2, e3, e4, e5));
// }
//
// static <T, E1, E2, E3, E4, E5, E6> Pattern<Tuple6<E1, E2, E3, E4, E5, E6>> of(
// Decomposition<T, Tuple6<E1, E2, E3, E4, E5, E6>> decomposition, E1 e1, E2 e2, E3 e3, E4 e4, E5 e5, E6 e6) {
// return Pattern.of(decomposition, Tuples.of(e1, e2, e3, e4, e5, e6));
// Decomposable<T, Tuple6<E1, E2, E3, E4, E5, E6>> decomposable, E1 e1, E2 e2, E3 e3, E4 e4, E5 e5, E6 e6) {
// return Pattern.of(decomposable, Tuples.of(e1, e2, e3, e4, e5, e6));
// }
//
// static <T, E1, E2, E3, E4, E5, E6, E7> Pattern<Tuple7<E1, E2, E3, E4, E5, E6, E7>> of(
// Decomposition<T, Tuple7<E1, E2, E3, E4, E5, E6, E7>> decomposition, E1 e1, E2 e2, E3 e3, E4 e4, E5 e5,
// Decomposable<T, Tuple7<E1, E2, E3, E4, E5, E6, E7>> decomposable, E1 e1, E2 e2, E3 e3, E4 e4, E5 e5,
// E6 e6, E7 e7) {
// return Pattern.of(decomposition, Tuples.of(e1, e2, e3, e4, e5, e6, e7));
// return Pattern.of(decomposable, Tuples.of(e1, e2, e3, e4, e5, e6, e7));
// }
//
// static <T, E1, E2, E3, E4, E5, E6, E7, E8> Pattern<Tuple8<E1, E2, E3, E4, E5, E6, E7, E8>> of(
// Decomposition<T, Tuple8<E1, E2, E3, E4, E5, E6, E7, E8>> decomposition, E1 e1, E2 e2, E3 e3, E4 e4, E5 e5,
// Decomposable<T, Tuple8<E1, E2, E3, E4, E5, E6, E7, E8>> decomposable, E1 e1, E2 e2, E3 e3, E4 e4, E5 e5,
// E6 e6, E7 e7, E8 e8) {
// return Pattern.of(decomposition, Tuples.of(e1, e2, e3, e4, e5, e6, e7, e8));
// return Pattern.of(decomposable, Tuples.of(e1, e2, e3, e4, e5, e6, e7, e8));
// }
//
// static <T, E1, E2, E3, E4, E5, E6, E7, E8, E9> Pattern<Tuple9<E1, E2, E3, E4, E5, E6, E7, E8, E9>> of(
// Decomposition<T, Tuple9<E1, E2, E3, E4, E5, E6, E7, E8, E9>> decomposition, E1 e1, E2 e2, E3 e3, E4 e4,
// Decomposable<T, Tuple9<E1, E2, E3, E4, E5, E6, E7, E8, E9>> decomposable, E1 e1, E2 e2, E3 e3, E4 e4,
// E5 e5, E6 e6, E7 e7, E8 e8, E9 e9) {
// return Pattern.of(decomposition, Tuples.of(e1, e2, e3, e4, e5, e6, e7, e8, e9));
// return Pattern.of(decomposable, Tuples.of(e1, e2, e3, e4, e5, e6, e7, e8, e9));
// }
//
// static <T, E1, E2, E3, E4, E5, E6, E7, E8, E9, E10> Pattern<Tuple10<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10>> of(
// Decomposition<T, Tuple10<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10>> decomposition, E1 e1, E2 e2, E3 e3,
// Decomposable<T, Tuple10<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10>> decomposable, E1 e1, E2 e2, E3 e3,
// E4 e4, E5 e5, E6 e6, E7 e7, E8 e8, E9 e9, E10 e10) {
// return Pattern.of(decomposition, Tuples.of(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10));
// return Pattern.of(decomposable, Tuples.of(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10));
// }
//
// static <T, E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11> Pattern<Tuple11<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11>> of(
// Decomposition<T, Tuple11<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11>> decomposition, E1 e1, E2 e2, E3 e3,
// Decomposable<T, Tuple11<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11>> decomposable, E1 e1, E2 e2, E3 e3,
// E4 e4, E5 e5, E6 e6, E7 e7, E8 e8, E9 e9, E10 e10, E11 e11) {
// return Pattern.of(decomposition, Tuples.of(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11));
// return Pattern.of(decomposable, Tuples.of(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11));
// }
//
// static <T, E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12> Pattern<Tuple12<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12>> of(
// Decomposition<T, Tuple12<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12>> decomposition, E1 e1, E2 e2, E3 e3,
// Decomposable<T, Tuple12<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12>> decomposable, E1 e1, E2 e2, E3 e3,
// E4 e4, E5 e5, E6 e6, E7 e7, E8 e8, E9 e9, E10 e10, E11 e11, E12 e12) {
// return Pattern.of(decomposition, Tuples.of(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12));
// return Pattern.of(decomposable, Tuples.of(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12));
// }
//
// static <T, E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13> Pattern<Tuple13<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13>> of(
// Decomposition<T, Tuple13<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13>> decomposition, E1 e1, E2 e2, E3 e3,
// Decomposable<T, Tuple13<E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13>> decomposable, E1 e1, E2 e2, E3 e3,
// E4 e4, E5 e5, E6 e6, E7 e7, E8 e8, E9 e9, E10 e10, E11 e11, E12 e12, E13 e13) {
// return Pattern.of(decomposition, Tuples.of(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13));
// return Pattern.of(decomposable, Tuples.of(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13));
// }
}

0 comments on commit a6e313c

Please sign in to comment.