Skip to content

Commit 700d625

Browse files
committed
Adding Upcast
1 parent 06131c6 commit 700d625

File tree

3 files changed

+64
-0
lines changed

3 files changed

+64
-0
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
77
### Changed
88
- `ToMap` accepts an `Iterable` covariant in `Map.Entry`
99

10+
### Added
11+
- `Upcast` for safely casting up a type hierarchy
12+
1013
## [3.0.0] - 2018-05-04
1114
### Changed
1215
- ***Breaking Change***: `Sequence` now has two more type parameters to aid in inference
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.jnape.palatable.lambda.functions.builtin.fn1;
2+
3+
import com.jnape.palatable.lambda.functions.Fn1;
4+
5+
/**
6+
* Upcast a value of type <code>B</code> to a value of type <code>A</code> that <code>B</code> extends. This is
7+
* principally useful when dealing with parametric types that are invariant in their parameters and a cast is
8+
* necessary for compatibility purposes.
9+
* <p>
10+
* Example:
11+
* <pre>
12+
* {@code
13+
* Iterable<String> have = new ArrayList<>();
14+
* Iterable<CharSequence> want = map(upcast(), have); // necessary due to invariance in parameter
15+
* }
16+
* </pre>
17+
* <p>
18+
* Note that this is universally safe.
19+
*
20+
* @param <A> the covariant type
21+
* @param <B> the contravariant type
22+
*/
23+
public final class Upcast<A extends B, B> implements Fn1<A, B> {
24+
25+
private static final Upcast INSTANCE = new Upcast<>();
26+
27+
private Upcast() {
28+
}
29+
30+
@Override
31+
public B apply(A a) {
32+
return a;
33+
}
34+
35+
@SuppressWarnings("unchecked")
36+
public static <A extends B, B> Upcast<A, B> upcast() {
37+
return INSTANCE;
38+
}
39+
40+
public static <A extends B, B> B upcast(A a) {
41+
return Upcast.<A, B>upcast().apply(a);
42+
}
43+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.jnape.palatable.lambda.functions.builtin.fn1;
2+
3+
import org.junit.Test;
4+
5+
import static com.jnape.palatable.lambda.functions.builtin.fn1.Upcast.upcast;
6+
import static com.jnape.palatable.lambda.functions.builtin.fn2.Map.map;
7+
import static java.util.Arrays.asList;
8+
9+
public class UpcastTest {
10+
11+
@Test
12+
@SuppressWarnings("unused")
13+
public void castsUp() {
14+
Upcast<String, CharSequence> upcast = upcast();
15+
Iterable<String> strings = asList("foo", "bar");
16+
Iterable<CharSequence> charSequences = map(upcast, strings);
17+
}
18+
}

0 commit comments

Comments
 (0)