Skip to content

Commit dfbc3fa

Browse files
committed
Adding SetLens, lenses that operate on Sets
1 parent 700d625 commit dfbc3fa

File tree

3 files changed

+93
-0
lines changed

3 files changed

+93
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
99

1010
### Added
1111
- `Upcast` for safely casting up a type hierarchy
12+
- `SetLens`, lenses operating on `Set`s
1213

1314
## [3.0.0] - 2018-05-04
1415
### Changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package com.jnape.palatable.lambda.lens.lenses;
2+
3+
import com.jnape.palatable.lambda.lens.Lens;
4+
5+
import java.util.HashSet;
6+
import java.util.Set;
7+
import java.util.function.Function;
8+
9+
import static com.jnape.palatable.lambda.lens.Lens.simpleLens;
10+
11+
/**
12+
* Lenses that operate on {@link Set}s.
13+
*/
14+
public final class SetLens {
15+
16+
private SetLens() {
17+
}
18+
19+
/**
20+
* A lens that focuses on whether a {@link Set} contains some value <code>a</code>. Note that <code>copyFn</code> is
21+
* used to avoid mutating the {@link Set} in question.
22+
*
23+
* @param copyFn the copy function
24+
* @param a the value in question
25+
* @param <A> the value type
26+
* @param <SetA> the set to focus on
27+
* @return a lens that focuses on a value's inclusion in a given {@link Set}
28+
*/
29+
public static <A, SetA extends Set<A>> Lens.Simple<SetA, Boolean> contains(
30+
Function<? super SetA, ? extends SetA> copyFn, A a) {
31+
return simpleLens(setA -> setA.contains(a),
32+
(setA, include) -> {
33+
SetA copy = copyFn.apply(setA);
34+
if (include) copy.add(a);
35+
else copy.remove(a);
36+
return copy;
37+
});
38+
}
39+
40+
/**
41+
* A lens that focuses on whether a {@link Set} contains some value <code>a</code>. Like {@link #contains(Function,
42+
* Object)} but with an implicit copy function that produces <code>{@link HashSet}s</code>.
43+
*
44+
* @param a the value in question
45+
* @param <A> the value type
46+
* @return a lens that focuses on a value's inclusion in a given {@link Set}
47+
*/
48+
public static <A> Lens.Simple<Set<A>, Boolean> contains(A a) {
49+
return contains(HashSet::new, a);
50+
}
51+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.jnape.palatable.lambda.lens.lenses;
2+
3+
import org.junit.Test;
4+
5+
import java.util.HashSet;
6+
import java.util.TreeSet;
7+
8+
import static com.jnape.palatable.lambda.lens.functions.Set.set;
9+
import static java.util.Arrays.asList;
10+
import static java.util.Collections.emptySet;
11+
import static java.util.Collections.singleton;
12+
import static org.hamcrest.CoreMatchers.instanceOf;
13+
import static org.junit.Assert.assertThat;
14+
import static testsupport.assertion.LensAssert.assertLensLawfulness;
15+
16+
public class SetLensTest {
17+
18+
@Test
19+
public void containsWithCopyFn() {
20+
assertLensLawfulness(SetLens.contains(HashSet::new, 1),
21+
asList(emptySet(),
22+
singleton(1),
23+
singleton(2),
24+
new HashSet<>(asList(1, 2)),
25+
new HashSet<>(asList(2, 3))),
26+
asList(true, false));
27+
assertThat(set(SetLens.contains(TreeSet::new, 1), true, emptySet()), instanceOf(TreeSet.class));
28+
}
29+
30+
@Test
31+
public void containsWithoutCopyFn() {
32+
assertLensLawfulness(SetLens.contains(1),
33+
asList(emptySet(),
34+
singleton(1),
35+
singleton(2),
36+
new HashSet<>(asList(1, 2)),
37+
new HashSet<>(asList(2, 3))),
38+
asList(true, false));
39+
assertThat(set(SetLens.contains(1), true, emptySet()), instanceOf(HashSet.class));
40+
}
41+
}

0 commit comments

Comments
 (0)