Skip to content

Commit 7fe05d4

Browse files
committed
spike
1 parent d2e0c1d commit 7fe05d4

File tree

5 files changed

+263
-0
lines changed

5 files changed

+263
-0
lines changed

src/main/java/com/jnape/palatable/lambda/functions/specialized/Predicate.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ default <Z> Predicate<Z> compose(Function<? super Z, ? extends A> before) {
3232
return Fn1.super.compose(before)::apply;
3333
}
3434

35+
/**
36+
* {@inheritDoc}
37+
*/
38+
@Override
39+
default <Z> Predicate<Z> contraMap(Function<? super Z, ? extends A> fn) {
40+
return Fn1.super.contraMap(fn)::apply;
41+
}
42+
3543
/**
3644
* {@inheritDoc}
3745
*/
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package com.jnape.palatable.lambda.structural;
2+
3+
import com.jnape.palatable.lambda.adt.Maybe;
4+
import com.jnape.palatable.lambda.adt.hlist.HList.HCons;
5+
import com.jnape.palatable.lambda.adt.hlist.SingletonHList;
6+
import com.jnape.palatable.lambda.adt.hlist.Tuple2;
7+
import com.jnape.palatable.lambda.functions.Fn1;
8+
import com.jnape.palatable.lambda.functions.Fn2;
9+
import com.jnape.palatable.lambda.functions.specialized.Predicate;
10+
11+
import java.util.function.Function;
12+
13+
import static com.jnape.palatable.lambda.adt.Maybe.just;
14+
import static com.jnape.palatable.lambda.functions.builtin.fn2.Into.into;
15+
import static com.jnape.palatable.lambda.functions.builtin.fn2.Into1.into1;
16+
17+
public abstract class Case {
18+
19+
private Case() {
20+
}
21+
22+
public static final class Partial<Fields extends HCons, R> extends Case implements Fn1<Fields, Maybe<R>> {
23+
24+
private final Predicate<Fields> pred;
25+
private final Function<Fields, R> fn;
26+
27+
private Partial(Predicate<Fields> pred, Function<Fields, R> fn) {
28+
this.pred = pred;
29+
this.fn = fn;
30+
}
31+
32+
@Override
33+
public Maybe<R> apply(Fields fields) {
34+
return just(fields).filter(pred).fmap(fn);
35+
}
36+
}
37+
38+
public static final class Total<Fields extends HCons, R> extends Case implements Fn1<Fields, R> {
39+
private final Function<Fields, R> fn;
40+
41+
private Total(Function<Fields, R> fn) {
42+
this.fn = fn;
43+
}
44+
45+
@Override
46+
public R apply(Fields fields) {
47+
return fn.apply(fields);
48+
}
49+
}
50+
51+
public static <A, B, R> Total<Tuple2<A, B>, R> of(Fn2<? super A, ? super B, ? extends R> fn) {
52+
return new Total<>(into(fn.toBiFunction()));
53+
}
54+
55+
public static <A, R> Total<SingletonHList<A>, R> of(CatchAll aPredicate,
56+
Fn1<A, R> fn) {
57+
return new Total<>(into1(fn));
58+
}
59+
60+
//todo: overload that explicitly takes Fn<Fields, R> ?
61+
62+
public static <A, R> Partial<SingletonHList<A>, R> of(Predicate<A> pred,
63+
Fn1<A, R> fn) {
64+
65+
return new Partial<>(pred.contraMap(HCons::head), into1(fn));
66+
}
67+
68+
public static <A, B, R> Total<Tuple2<A, B>, R> of(CatchAll __,
69+
CatchAll ___,
70+
Fn2<? super A, ? super B, ? extends R> fn) {
71+
return new Total<>(into(fn.toBiFunction()));
72+
}
73+
74+
public static <A, B, R> Partial<Tuple2<A, B>, R> of(Predicate<? super A> aPredicate,
75+
Predicate<? super B> bPredicate,
76+
Fn2<? super A, ? super B, ? extends R> fn) {
77+
return new Partial<>(t -> aPredicate.test(t._1()) && bPredicate.test(t._2()),
78+
into(fn.toBiFunction()));
79+
}
80+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package com.jnape.palatable.lambda.structural;
2+
3+
import com.jnape.palatable.lambda.adt.hlist.HList.HCons;
4+
5+
import static com.jnape.palatable.lambda.functions.builtin.fn2.Cons.cons;
6+
import static com.jnape.palatable.lambda.structural.Match.partial;
7+
import static com.jnape.palatable.lambda.structural.Match.total;
8+
import static java.util.Arrays.asList;
9+
import static java.util.Collections.emptyList;
10+
11+
public class Cases {
12+
13+
private Cases() {
14+
}
15+
16+
public static <Fields extends HCons, R> Match.Total<Fields, R> cases(Case.Partial<Fields, R> partialCase,
17+
Case.Total<Fields, R> totalCase) {
18+
return cases(partialCase).or(cases(totalCase));
19+
}
20+
21+
public static <Fields extends HCons, R> Match.Total<Fields, R> cases(Case.Partial<Fields, R> partialCase1,
22+
Case.Partial<Fields, R> partialCase2,
23+
Case.Total<Fields, R> totalCase) {
24+
return cases(partialCase1, partialCase2).or(cases(totalCase));
25+
}
26+
27+
public static <Fields extends HCons, R> Match.Total<Fields, R> cases(Case.Partial<Fields, R> partialCase1,
28+
Case.Partial<Fields, R> partialCase2,
29+
Case.Partial<Fields, R> partialCase3,
30+
Case.Total<Fields, R> totalCase) {
31+
return cases(partialCase1, partialCase2, partialCase3).or(cases(totalCase));
32+
}
33+
34+
public static <Fields extends HCons, R> Match.Total<Fields, R> cases(Case.Partial<Fields, R> partialCase1,
35+
Case.Partial<Fields, R> partialCase2,
36+
Case.Partial<Fields, R> partialCase3,
37+
Case.Partial<Fields, R> partialCase4,
38+
Case.Total<Fields, R> totalCase) {
39+
return cases(partialCase1, partialCase2, partialCase3, partialCase4).or(cases(totalCase));
40+
}
41+
42+
public static <Fields extends HCons, R> Match.Total<Fields, R> cases(Case.Partial<Fields, R> partialCase1,
43+
Case.Partial<Fields, R> partialCase2,
44+
Case.Partial<Fields, R> partialCase3,
45+
Case.Partial<Fields, R> partialCase4,
46+
Case.Partial<Fields, R> partialCase5,
47+
Case.Total<Fields, R> totalCase) {
48+
return cases(partialCase1, partialCase2, partialCase3, partialCase4, partialCase5).or(cases(totalCase));
49+
}
50+
51+
public static <Fields extends HCons, R> Match.Total<Fields, R> cases(Case.Partial<Fields, R> partialCase1,
52+
Case.Partial<Fields, R> partialCase2,
53+
Case.Partial<Fields, R> partialCase3,
54+
Case.Partial<Fields, R> partialCase4,
55+
Case.Partial<Fields, R> partialCase5,
56+
Case.Partial<Fields, R> partialCase6,
57+
Case.Total<Fields, R> totalCase) {
58+
return cases(partialCase1, partialCase2, partialCase3, partialCase4, partialCase5, partialCase6).or(cases(totalCase));
59+
}
60+
61+
public static <Fields extends HCons, R> Match.Total<Fields, R> cases(Case.Partial<Fields, R> partialCase1,
62+
Case.Partial<Fields, R> partialCase2,
63+
Case.Partial<Fields, R> partialCase3,
64+
Case.Partial<Fields, R> partialCase4,
65+
Case.Partial<Fields, R> partialCase5,
66+
Case.Partial<Fields, R> partialCase6,
67+
Case.Partial<Fields, R> partialCase7,
68+
Case.Total<Fields, R> totalCase) {
69+
return total(asList(partialCase1, partialCase2, partialCase3, partialCase4, partialCase5, partialCase6, partialCase7),
70+
totalCase);
71+
}
72+
73+
public static <Fields extends HCons, R> Match.Total<Fields, R> cases(Case.Partial<Fields, R> partialCase1,
74+
Case.Partial<Fields, R> partialCase2,
75+
Case.Partial<Fields, R> partialCase3,
76+
Case.Partial<Fields, R> partialCase4,
77+
Case.Partial<Fields, R> partialCase5,
78+
Case.Partial<Fields, R> partialCase6,
79+
Case.Partial<Fields, R> partialCase7,
80+
Case.Partial<Fields, R> partialCase8,
81+
Case.Total<Fields, R> totalCase) {
82+
return cases(partialCase1, partialCase2, partialCase3, partialCase4, partialCase5, partialCase6, partialCase7, partialCase8)
83+
.or(cases(totalCase));
84+
}
85+
86+
public static <Fields extends HCons, R> Match.Total<Fields, R> cases(Case.Total<Fields, R> totalCase) {
87+
return total(emptyList(), totalCase);
88+
}
89+
90+
@SafeVarargs
91+
public static <Fields extends HCons, R> Match.Partial<Fields, R> cases(Case.Partial<Fields, R> partialCase,
92+
Case.Partial<Fields, R>... more) {
93+
return partial(cons(partialCase, asList(more)));
94+
}
95+
96+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.jnape.palatable.lambda.structural;
2+
3+
import com.jnape.palatable.lambda.functions.specialized.Predicate;
4+
5+
//todo: this sort of sucks having to have a separate type to distinguish this, but maybe can't be helped
6+
public final class CatchAll implements Predicate<Object> {
7+
8+
public static final CatchAll __ = new CatchAll();
9+
10+
private CatchAll() {
11+
}
12+
13+
@Override
14+
public Boolean apply(Object o) {
15+
return true;
16+
}
17+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package com.jnape.palatable.lambda.structural;
2+
3+
import com.jnape.palatable.lambda.adt.Maybe;
4+
import com.jnape.palatable.lambda.adt.hlist.HList;
5+
import com.jnape.palatable.lambda.functions.Fn1;
6+
7+
import static com.jnape.palatable.lambda.functions.builtin.fn1.CatMaybes.catMaybes;
8+
import static com.jnape.palatable.lambda.functions.builtin.fn1.Head.head;
9+
import static com.jnape.palatable.lambda.functions.builtin.fn2.Map.map;
10+
import static com.jnape.palatable.lambda.monoid.builtin.Concat.concat;
11+
12+
public abstract class Match {
13+
private Match() {
14+
}
15+
16+
public static <Fields extends HList.HCons, R> Partial<Fields, R> partial(
17+
Iterable<Case.Partial<Fields, R>> partialCases) {
18+
return new Partial<>(partialCases);
19+
}
20+
21+
public static <Fields extends HList.HCons, R> Total<Fields, R> total(Iterable<Case.Partial<Fields, R>> partialCases,
22+
Case.Total<Fields, R> totalCase) {
23+
return new Total<>(partialCases, totalCase);
24+
}
25+
26+
public static final class Partial<Fields extends HList.HCons, R> implements Fn1<Fields, Maybe<R>> {
27+
private final Iterable<Case.Partial<Fields, R>> cases;
28+
29+
private Partial(Iterable<Case.Partial<Fields, R>> cases) {
30+
this.cases = cases;
31+
}
32+
33+
@Override
34+
public Maybe<R> apply(Fields fields) {
35+
return head(catMaybes(map(c -> c.apply(fields), cases)));
36+
}
37+
38+
public Partial<Fields, R> or(Partial<Fields, R> other) {
39+
return new Partial<>(concat(cases, other.cases));
40+
}
41+
42+
public Total<Fields, R> or(Total<Fields, R> other) {
43+
return new Total<>(concat(cases, other.partialCases), other.totalCase);
44+
}
45+
}
46+
47+
public static final class Total<Fields extends HList.HCons, R> implements Fn1<Fields, R> {
48+
private final Iterable<Case.Partial<Fields, R>> partialCases;
49+
private final Case.Total<Fields, R> totalCase;
50+
51+
private Total(Iterable<Case.Partial<Fields, R>> partialCases,
52+
Case.Total<Fields, R> totalCase) {
53+
this.partialCases = partialCases;
54+
this.totalCase = totalCase;
55+
}
56+
57+
@Override
58+
public R apply(Fields fields) {
59+
return partial(partialCases).apply(fields).orElseGet(() -> totalCase.apply(fields));
60+
}
61+
}
62+
}

0 commit comments

Comments
 (0)