Skip to content

Commit 6a1ca16

Browse files
committed
Adding both, for dually applying two functions invariant in the argument
1 parent 14a21c6 commit 6a1ca16

File tree

3 files changed

+67
-0
lines changed

3 files changed

+67
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
2222
- `These`, a `CoProduct3` of `A`, `B`, or `Tuple2<A,B>`
2323
- `Span`, for splitting an `Iterable` into contiguous elements matching a predicate
2424
- `MagnetizeBy` and `Magnetize`, for grouping elements by pairwise predicate tests
25+
- `Both`, for dually applying two functions and producing a `Tuple2` of their results
2526

2627
### Deprecated
2728
- `Either#trying` in favor of `Try#trying`
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package com.jnape.palatable.lambda.functions.builtin.fn2;
2+
3+
import com.jnape.palatable.lambda.adt.hlist.Tuple2;
4+
import com.jnape.palatable.lambda.functions.Fn1;
5+
import com.jnape.palatable.lambda.functions.Fn3;
6+
7+
import java.util.function.Function;
8+
9+
/**
10+
* Given two functions <code>f</code> and <code>g</code>, produce a
11+
* <code>{@link Fn1}&lt;A, {@link Tuple2}&lt;B, C&gt;&gt;</code> (the dual application of both functions).
12+
*
13+
* @param <A> both function's input type
14+
* @param <B> the first function return type
15+
* @param <C> the second function return type
16+
*/
17+
public final class Both<A, B, C> implements Fn3<Function<? super A, ? extends B>, Function<? super A, ? extends C>, A, Tuple2<B, C>> {
18+
19+
private static final Both INSTANCE = new Both();
20+
21+
private Both() {
22+
}
23+
24+
@Override
25+
public Tuple2<B, C> apply(Function<? super A, ? extends B> f,
26+
Function<? super A, ? extends C> g,
27+
A a) {
28+
return Tuple2.fill(a).biMap(f, g);
29+
}
30+
31+
@SuppressWarnings("unchecked")
32+
public static <A, B, C> Both<A, B, C> both() {
33+
return INSTANCE;
34+
}
35+
36+
public static <A, B, C> Fn1<Function<? super A, ? extends C>, Fn1<A, Tuple2<B, C>>> both(
37+
Function<? super A, ? extends B> f) {
38+
return Both.<A, B, C>both().apply(f);
39+
}
40+
41+
public static <A, B, C> Fn1<A, Tuple2<B, C>> both(Function<? super A, ? extends B> f,
42+
Function<? super A, ? extends C> g) {
43+
return Both.<A, B, C>both(f).apply(g);
44+
}
45+
46+
public static <A, B, C> Tuple2<B, C> both(Function<? super A, ? extends B> f,
47+
Function<? super A, ? extends C> g,
48+
A a) {
49+
return Both.<A, B, C>both(f, g).apply(a);
50+
}
51+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.jnape.palatable.lambda.functions.builtin.fn2;
2+
3+
import org.junit.Test;
4+
5+
import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
6+
import static com.jnape.palatable.lambda.functions.builtin.fn2.Both.both;
7+
import static org.junit.Assert.assertEquals;
8+
9+
public class BothTest {
10+
11+
@Test
12+
public void duallyAppliesTwoFunctionsToSameInput() {
13+
assertEquals(tuple(1, -1), both(x -> x + 1, x -> x - 1, 0));
14+
}
15+
}

0 commit comments

Comments
 (0)