forked from palatable/lambda
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFunctorLaws.java
More file actions
39 lines (32 loc) · 1.54 KB
/
FunctorLaws.java
File metadata and controls
39 lines (32 loc) · 1.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package testsupport.traits;
import com.jnape.palatable.lambda.functor.Functor;
import com.jnape.palatable.lambda.monoid.builtin.Present;
import com.jnape.palatable.traitor.traits.Trait;
import java.util.Optional;
import java.util.function.Function;
import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly;
import static java.util.Arrays.asList;
import static java.util.function.Function.identity;
public class FunctorLaws<F extends Functor> implements Trait<Functor<?, F>> {
@Override
public void test(Functor<?, F> f) {
Present.<String>present((x, y) -> x + "\n\t - " + y)
.reduceLeft(asList(testIdentity(f), testComposition(f)))
.ifPresent(s -> {
throw new AssertionError("The following Functor laws did not hold for instance of " + f.getClass() + ": \n\t - " + s);
});
}
private Optional<String> testIdentity(Functor<?, F> f) {
return f.fmap(identity()).equals(f)
? Optional.empty()
: Optional.of("identity (f.fmap(identity()).equals(f))");
}
private Optional<String> testComposition(Functor<?, F> functor) {
Functor<Integer, F> subject = functor.fmap(constantly(1));
Function<Integer, Integer> f = x -> x * 3;
Function<Integer, Integer> g = x -> x - 2;
return subject.fmap(f.compose(g)).equals(subject.fmap(g).fmap(f))
? Optional.empty()
: Optional.of("composition (functor.fmap(f.compose(g)).equals(functor.fmap(g).fmap(f)))");
}
}