Skip to content

Commit 803c2c9

Browse files
committed
Default applicative zip evaluation order is now stable left to right
- reduction in LiftA2-7 type parameters
1 parent c78ed71 commit 803c2c9

File tree

24 files changed

+378
-512
lines changed

24 files changed

+378
-512
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
66
## [Unreleased]
77
### Changed
88
- ***Breaking Change***: `MonadT` is now witnessed by a parameter for better subtyping
9+
- ***Breaking Change***: `Applicative#zip` and derivatives evaluate from left to right now across the board.
910
- `Alter` now merely requires an `Fn1` instead of an explicit `Effect`
1011
- `IO` now internally trampolines all forms of composition, including lazyZip;
1112
sequencing very large iterables of IO will work, if you have the heap, and

src/main/java/com/jnape/palatable/lambda/adt/These.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,13 @@ public final <C, D> These<C, D> biMap(Fn1<? super A, ? extends C> lFn,
4949
*/
5050
@Override
5151
public final <C> These<A, C> flatMap(Fn1<? super B, ? extends Monad<C, These<A, ?>>> f) {
52-
return match(These::a, b -> f.apply(b).coerce(), into((a, b) -> f.apply(b).<These<A, C>>coerce().biMapL(constantly(a))));
52+
return match(These::a,
53+
b -> f.apply(b).coerce(),
54+
into((a, b) -> f.apply(b)
55+
.<These<A, C>>coerce()
56+
.match(constantly(a(a)),
57+
c -> both(a, c),
58+
into((__, c) -> both(a, c)))));
5359
}
5460

5561
/**

src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LiftA2.java

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,54 +12,43 @@
1212
* @param <A> the function's first argument type
1313
* @param <B> the function's second argument type
1414
* @param <C> the function's return type
15-
* @param <App> the applicative unification type
16-
* @param <AppA> the inferred first applicative argument type
17-
* @param <AppB> the inferred second applicative argument type
15+
* @param <App> the applicative witness
1816
* @param <AppC> the inferred applicative return type
1917
* @see Applicative#zip(Applicative)
2018
*/
21-
public final class LiftA2<A, B, C, App extends Applicative<?, App>,
22-
AppA extends Applicative<A, App>,
23-
AppB extends Applicative<B, App>,
24-
AppC extends Applicative<C, App>> implements
25-
Fn3<Fn2<? super A, ? super B, ? extends C>, AppA, AppB, AppC> {
19+
public final class LiftA2<A, B, C, App extends Applicative<?, App>, AppC extends Applicative<C, App>> implements
20+
Fn3<Fn2<? super A, ? super B, ? extends C>, Applicative<A, App>, Applicative<B, App>, AppC> {
2621

27-
private static final LiftA2<?, ?, ?, ?, ?, ?, ?> INSTANCE = new LiftA2<>();
22+
private static final LiftA2<?, ?, ?, ?, ?> INSTANCE = new LiftA2<>();
2823

2924
private LiftA2() {
3025
}
3126

3227
@Override
33-
public AppC checkedApply(Fn2<? super A, ? super B, ? extends C> fn, AppA appA, AppB appB) {
34-
return appB.<C>zip(appA.fmap(fn)).coerce();
28+
public AppC checkedApply(Fn2<? super A, ? super B, ? extends C> fn,
29+
Applicative<A, App> appA,
30+
Applicative<B, App> appB) {
31+
return appA.<C>zip(appB.fmap(b -> a -> fn.apply(a, b))).coerce();
3532
}
3633

3734
@SuppressWarnings("unchecked")
38-
public static <A, B, C, App extends Applicative<?, App>, AppA extends Applicative<A, App>,
39-
AppB extends Applicative<B, App>,
40-
AppC extends Applicative<C, App>> LiftA2<A, B, C, App, AppA, AppB, AppC> liftA2() {
41-
return (LiftA2<A, B, C, App, AppA, AppB, AppC>) INSTANCE;
35+
public static <A, B, C, App extends Applicative<?, App>, AppC extends Applicative<C, App>>
36+
LiftA2<A, B, C, App, AppC> liftA2() {
37+
return (LiftA2<A, B, C, App, AppC>) INSTANCE;
4238
}
4339

44-
public static <A, B, C, App extends Applicative<?, App>, AppA extends Applicative<A, App>,
45-
AppB extends Applicative<B, App>,
46-
AppC extends Applicative<C, App>> Fn2<AppA, AppB, AppC> liftA2(
47-
Fn2<? super A, ? super B, ? extends C> fn) {
48-
return LiftA2.<A, B, C, App, AppA, AppB, AppC>liftA2().apply(fn);
40+
public static <A, B, C, App extends Applicative<?, App>, AppC extends Applicative<C, App>>
41+
Fn2<Applicative<A, App>, Applicative<B, App>, AppC> liftA2(Fn2<? super A, ? super B, ? extends C> fn) {
42+
return LiftA2.<A, B, C, App, AppC>liftA2().apply(fn);
4943
}
5044

51-
public static <A, B, C, App extends Applicative<?, App>, AppA extends Applicative<A, App>,
52-
AppB extends Applicative<B, App>,
53-
AppC extends Applicative<C, App>> Fn1<AppB, AppC> liftA2(Fn2<? super A, ? super B, ? extends C> fn,
54-
AppA appA) {
55-
return LiftA2.<A, B, C, App, AppA, AppB, AppC>liftA2(fn).apply(appA);
45+
public static <A, B, C, App extends Applicative<?, App>, AppC extends Applicative<C, App>>
46+
Fn1<Applicative<B, App>, AppC> liftA2(Fn2<? super A, ? super B, ? extends C> fn, Applicative<A, App> appA) {
47+
return LiftA2.<A, B, C, App, AppC>liftA2(fn).apply(appA);
5648
}
5749

58-
public static <A, B, C, App extends Applicative<?, App>, AppA extends Applicative<A, App>,
59-
AppB extends Applicative<B, App>,
60-
AppC extends Applicative<C, App>> AppC liftA2(Fn2<? super A, ? super B, ? extends C> fn,
61-
AppA appA,
62-
AppB appB) {
63-
return LiftA2.<A, B, C, App, AppA, AppB, AppC>liftA2(fn, appA).apply(appB);
50+
public static <A, B, C, App extends Applicative<?, App>, AppC extends Applicative<C, App>>
51+
AppC liftA2(Fn2<? super A, ? super B, ? extends C> fn, Applicative<A, App> appA, Applicative<B, App> appB) {
52+
return LiftA2.<A, B, C, App, AppC>liftA2(fn, appA).apply(appB);
6453
}
6554
}

src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/LiftA3.java

Lines changed: 24 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -14,74 +14,49 @@
1414
* @param <B> the function's second argument type
1515
* @param <C> the function's third argument type
1616
* @param <D> the function's return type
17-
* @param <App> the applicative unification type
18-
* @param <AppA> the inferred first applicative argument type
19-
* @param <AppB> the inferred second applicative argument type
20-
* @param <AppC> the inferred third applicative argument type
17+
* @param <App> the applicative witness
2118
* @param <AppD> the inferred applicative return type
2219
* @see Applicative#zip(Applicative)
2320
*/
24-
public final class LiftA3<A, B, C, D,
25-
App extends Applicative<?, App>,
26-
AppA extends Applicative<A, App>,
27-
AppB extends Applicative<B, App>,
28-
AppC extends Applicative<C, App>,
29-
AppD extends Applicative<D, App>> implements Fn4<Fn3<A, B, C, D>, AppA, AppB, AppC, AppD> {
21+
public final class LiftA3<A, B, C, D, App extends Applicative<?, App>, AppD extends Applicative<D, App>> implements
22+
Fn4<Fn3<A, B, C, D>, Applicative<A, App>, Applicative<B, App>, Applicative<C, App>, AppD> {
3023

31-
private static final LiftA3<?, ?, ?, ?, ?, ?, ?, ?, ?> INSTANCE = new LiftA3<>();
24+
private static final LiftA3<?, ?, ?, ?, ?, ?> INSTANCE = new LiftA3<>();
3225

3326
private LiftA3() {
3427
}
3528

3629
@Override
37-
public AppD checkedApply(Fn3<A, B, C, D> fn, AppA appA, AppB appB, AppC appC) {
38-
return appC.zip(appB.zip(appA.fmap(fn))).coerce();
30+
public AppD checkedApply(Fn3<A, B, C, D> fn,
31+
Applicative<A, App> appA,
32+
Applicative<B, App> appB,
33+
Applicative<C, App> appC) {
34+
return appA.<D>zip(appB.zip(appC.fmap(c -> b -> a -> fn.apply(a, b, c)))).coerce();
3935
}
4036

4137
@SuppressWarnings("unchecked")
42-
public static <A, B, C, D,
43-
App extends Applicative<?, App>,
44-
AppA extends Applicative<A, App>,
45-
AppB extends Applicative<B, App>,
46-
AppC extends Applicative<C, App>,
47-
AppD extends Applicative<D, App>> LiftA3<A, B, C, D, App, AppA, AppB, AppC, AppD> liftA3() {
48-
return (LiftA3<A, B, C, D, App, AppA, AppB, AppC, AppD>) INSTANCE;
38+
public static <A, B, C, D, App extends Applicative<?, App>, AppD extends Applicative<D, App>>
39+
LiftA3<A, B, C, D, App, AppD> liftA3() {
40+
return (LiftA3<A, B, C, D, App, AppD>) INSTANCE;
4941
}
5042

51-
public static <A, B, C, D,
52-
App extends Applicative<?, App>,
53-
AppA extends Applicative<A, App>,
54-
AppB extends Applicative<B, App>,
55-
AppC extends Applicative<C, App>,
56-
AppD extends Applicative<D, App>> Fn3<AppA, AppB, AppC, AppD> liftA3(Fn3<A, B, C, D> fn) {
57-
return LiftA3.<A, B, C, D, App, AppA, AppB, AppC, AppD>liftA3().apply(fn);
43+
public static <A, B, C, D, App extends Applicative<?, App>, AppD extends Applicative<D, App>>
44+
Fn3<Applicative<A, App>, Applicative<B, App>, Applicative<C, App>, AppD> liftA3(Fn3<A, B, C, D> fn) {
45+
return LiftA3.<A, B, C, D, App, AppD>liftA3().apply(fn);
5846
}
5947

60-
public static <A, B, C, D,
61-
App extends Applicative<?, App>,
62-
AppA extends Applicative<A, App>,
63-
AppB extends Applicative<B, App>,
64-
AppC extends Applicative<C, App>,
65-
AppD extends Applicative<D, App>> Fn2<AppB, AppC, AppD> liftA3(Fn3<A, B, C, D> fn, AppA appA) {
66-
return LiftA3.<A, B, C, D, App, AppA, AppB, AppC, AppD>liftA3(fn).apply(appA);
48+
public static <A, B, C, D, App extends Applicative<?, App>, AppD extends Applicative<D, App>>
49+
Fn2<Applicative<B, App>, Applicative<C, App>, AppD> liftA3(Fn3<A, B, C, D> fn, Applicative<A, App> appA) {
50+
return LiftA3.<A, B, C, D, App, AppD>liftA3(fn).apply(appA);
6751
}
6852

69-
public static <A, B, C, D,
70-
App extends Applicative<?, App>,
71-
AppA extends Applicative<A, App>,
72-
AppB extends Applicative<B, App>,
73-
AppC extends Applicative<C, App>,
74-
AppD extends Applicative<D, App>> Fn1<AppC, AppD> liftA3(Fn3<A, B, C, D> fn, AppA appA, AppB appB) {
75-
return LiftA3.<A, B, C, D, App, AppA, AppB, AppC, AppD>liftA3(fn, appA).apply(appB);
53+
public static <A, B, C, D, App extends Applicative<?, App>, AppD extends Applicative<D, App>>
54+
Fn1<Applicative<C, App>, AppD> liftA3(Fn3<A, B, C, D> fn, Applicative<A, App> appA, Applicative<B, App> appB) {
55+
return LiftA3.<A, B, C, D, App, AppD>liftA3(fn, appA).apply(appB);
7656
}
7757

78-
public static <A, B, C, D,
79-
App extends Applicative<?, App>,
80-
AppA extends Applicative<A, App>,
81-
AppB extends Applicative<B, App>,
82-
AppC extends Applicative<C, App>,
83-
AppD extends Applicative<D, App>> AppD liftA3(Fn3<A, B, C, D> fn, AppA appA, AppB appB,
84-
AppC appC) {
85-
return LiftA3.<A, B, C, D, App, AppA, AppB, AppC, AppD>liftA3(fn, appA, appB).apply(appC);
58+
public static <A, B, C, D, App extends Applicative<?, App>, AppD extends Applicative<D, App>>
59+
AppD liftA3(Fn3<A, B, C, D> fn, Applicative<A, App> appA, Applicative<B, App> appB, Applicative<C, App> appC) {
60+
return LiftA3.<A, B, C, D, App, AppD>liftA3(fn, appA, appB).apply(appC);
8661
}
8762
}

src/main/java/com/jnape/palatable/lambda/functions/builtin/fn5/LiftA4.java

Lines changed: 37 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -16,93 +16,64 @@
1616
* @param <C> the function's third argument type
1717
* @param <D> the function's fourth argument type
1818
* @param <E> the function's return type
19-
* @param <App> the applicative unification type
20-
* @param <AppA> the inferred first applicative argument type
21-
* @param <AppB> the inferred second applicative argument type
22-
* @param <AppC> the inferred third applicative argument type
23-
* @param <AppD> the inferred fourth applicative argument type
19+
* @param <App> the applicative witness
2420
* @param <AppE> the inferred applicative return type
2521
* @see Applicative#zip(Applicative)
2622
*/
27-
public final class LiftA4<A, B, C, D, E,
28-
App extends Applicative<?, App>,
29-
AppA extends Applicative<A, App>,
30-
AppB extends Applicative<B, App>,
31-
AppC extends Applicative<C, App>,
32-
AppD extends Applicative<D, App>,
33-
AppE extends Applicative<E, App>> implements Fn5<Fn4<A, B, C, D, E>, AppA, AppB, AppC, AppD, AppE> {
23+
public final class LiftA4<A, B, C, D, E, App extends Applicative<?, App>, AppE extends Applicative<E, App>> implements
24+
Fn5<Fn4<A, B, C, D, E>, Applicative<A, App>, Applicative<B, App>, Applicative<C, App>, Applicative<D, App>,
25+
AppE> {
3426

35-
private static final LiftA4<?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?> INSTANCE = new LiftA4<>();
27+
private static final LiftA4<?, ?, ?, ?, ?, ?, ?> INSTANCE = new LiftA4<>();
3628

3729
private LiftA4() {
3830
}
3931

4032
@Override
41-
public AppE checkedApply(Fn4<A, B, C, D, E> fn, AppA appA, AppB appB, AppC appC, AppD appD) {
42-
return appD.zip(appC.zip(appB.zip(appA.fmap(fn)))).coerce();
33+
public AppE checkedApply(Fn4<A, B, C, D, E> fn, Applicative<A, App> appA, Applicative<B, App> appB,
34+
Applicative<C, App> appC, Applicative<D, App> appD) {
35+
return appA.<E>zip(appB.zip(appC.zip(appD.fmap(d -> c -> b -> a -> fn.apply(a, b, c, d))))).coerce();
4336
}
4437

4538
@SuppressWarnings("unchecked")
46-
public static <A, B, C, D, E,
47-
App extends Applicative<?, App>,
48-
AppA extends Applicative<A, App>,
49-
AppB extends Applicative<B, App>,
50-
AppC extends Applicative<C, App>,
51-
AppD extends Applicative<D, App>,
52-
AppE extends Applicative<E, App>> LiftA4<A, B, C, D, E, App, AppA, AppB, AppC, AppD, AppE> liftA4() {
53-
return (LiftA4<A, B, C, D, E, App, AppA, AppB, AppC, AppD, AppE>) INSTANCE;
39+
public static <A, B, C, D, E, App extends Applicative<?, App>, AppE extends Applicative<E, App>>
40+
LiftA4<A, B, C, D, E, App, AppE> liftA4() {
41+
return (LiftA4<A, B, C, D, E, App, AppE>) INSTANCE;
5442
}
5543

56-
public static <A, B, C, D, E,
57-
App extends Applicative<?, App>,
58-
AppA extends Applicative<A, App>,
59-
AppB extends Applicative<B, App>,
60-
AppC extends Applicative<C, App>,
61-
AppD extends Applicative<D, App>,
62-
AppE extends Applicative<E, App>> Fn4<AppA, AppB, AppC, AppD, AppE> liftA4(Fn4<A, B, C, D, E> fn) {
63-
return LiftA4.<A, B, C, D, E, App, AppA, AppB, AppC, AppD, AppE>liftA4().apply(fn);
44+
public static <A, B, C, D, E, App extends Applicative<?, App>, AppE extends Applicative<E, App>>
45+
Fn4<Applicative<A, App>, Applicative<B, App>, Applicative<C, App>, Applicative<D, App>, AppE> liftA4(
46+
Fn4<A, B, C, D, E> fn) {
47+
return LiftA4.<A, B, C, D, E, App, AppE>liftA4().apply(fn);
6448
}
6549

66-
public static <A, B, C, D, E,
67-
App extends Applicative<?, App>,
68-
AppA extends Applicative<A, App>,
69-
AppB extends Applicative<B, App>,
70-
AppC extends Applicative<C, App>,
71-
AppD extends Applicative<D, App>,
72-
AppE extends Applicative<E, App>> Fn3<AppB, AppC, AppD, AppE> liftA4(Fn4<A, B, C, D, E> fn, AppA appA) {
73-
return LiftA4.<A, B, C, D, E, App, AppA, AppB, AppC, AppD, AppE>liftA4(fn).apply(appA);
50+
public static <A, B, C, D, E, App extends Applicative<?, App>, AppE extends Applicative<E, App>>
51+
Fn3<Applicative<B, App>, Applicative<C, App>, Applicative<D, App>, AppE> liftA4(Fn4<A, B, C, D, E> fn,
52+
Applicative<A, App> appA) {
53+
return LiftA4.<A, B, C, D, E, App, AppE>liftA4(fn).apply(appA);
7454
}
7555

76-
public static <A, B, C, D, E,
77-
App extends Applicative<?, App>,
78-
AppA extends Applicative<A, App>,
79-
AppB extends Applicative<B, App>,
80-
AppC extends Applicative<C, App>,
81-
AppD extends Applicative<D, App>,
82-
AppE extends Applicative<E, App>> Fn2<AppC, AppD, AppE> liftA4(Fn4<A, B, C, D, E> fn, AppA appA,
83-
AppB appB) {
84-
return LiftA4.<A, B, C, D, E, App, AppA, AppB, AppC, AppD, AppE>liftA4(fn, appA).apply(appB);
56+
public static <A, B, C, D, E, App extends Applicative<?, App>, AppE extends Applicative<E, App>>
57+
Fn2<Applicative<C, App>, Applicative<D, App>, AppE> liftA4(Fn4<A, B, C, D, E> fn,
58+
Applicative<A, App> appA,
59+
Applicative<B, App> appB) {
60+
return LiftA4.<A, B, C, D, E, App, AppE>liftA4(fn, appA).apply(appB);
8561
}
8662

87-
public static <A, B, C, D, E,
88-
App extends Applicative<?, App>,
89-
AppA extends Applicative<A, App>,
90-
AppB extends Applicative<B, App>,
91-
AppC extends Applicative<C, App>,
92-
AppD extends Applicative<D, App>,
93-
AppE extends Applicative<E, App>> Fn1<AppD, AppE> liftA4(Fn4<A, B, C, D, E> fn, AppA appA, AppB appB,
94-
AppC appC) {
95-
return LiftA4.<A, B, C, D, E, App, AppA, AppB, AppC, AppD, AppE>liftA4(fn, appA, appB).apply(appC);
63+
public static <A, B, C, D, E, App extends Applicative<?, App>, AppE extends Applicative<E, App>>
64+
Fn1<Applicative<D, App>, AppE> liftA4(Fn4<A, B, C, D, E> fn,
65+
Applicative<A, App> appA,
66+
Applicative<B, App> appB,
67+
Applicative<C, App> appC) {
68+
return LiftA4.<A, B, C, D, E, App, AppE>liftA4(fn, appA, appB).apply(appC);
9669
}
9770

98-
public static <A, B, C, D, E,
99-
App extends Applicative<?, App>,
100-
AppA extends Applicative<A, App>,
101-
AppB extends Applicative<B, App>,
102-
AppC extends Applicative<C, App>,
103-
AppD extends Applicative<D, App>,
104-
AppE extends Applicative<E, App>> AppE liftA4(Fn4<A, B, C, D, E> fn, AppA appA, AppB appB,
105-
AppC appC, AppD appD) {
106-
return LiftA4.<A, B, C, D, E, App, AppA, AppB, AppC, AppD, AppE>liftA4(fn, appA, appB, appC).apply(appD);
71+
public static <A, B, C, D, E, App extends Applicative<?, App>, AppE extends Applicative<E, App>>
72+
AppE liftA4(Fn4<A, B, C, D, E> fn,
73+
Applicative<A, App> appA,
74+
Applicative<B, App> appB,
75+
Applicative<C, App> appC,
76+
Applicative<D, App> appD) {
77+
return LiftA4.<A, B, C, D, E, App, AppE>liftA4(fn, appA, appB, appC).apply(appD);
10778
}
10879
}

0 commit comments

Comments
 (0)