7
7
import com .jnape .palatable .lambda .functions .Fn3 ;
8
8
import com .jnape .palatable .lambda .functions .builtin .fn3 .LiftA2 ;
9
9
import com .jnape .palatable .lambda .functions .builtin .fn4 .LiftA3 ;
10
- import com .jnape .palatable .lambda .functor .Applicative ;
11
10
import com .jnape .palatable .lambda .functor .builtin .Lazy ;
12
11
import com .jnape .palatable .lambda .io .IO ;
13
12
import com .jnape .palatable .lambda .traversable .LambdaIterable ;
@@ -40,6 +39,7 @@ public void applicativesZipEmbeddedValuesWithEmbeddedFunctions() {
40
39
41
40
assertThat (just (9 ).zip (just (inc )), equalTo (just (10 )));
42
41
assertThat (just (15 ).zip (just (inc )), equalTo (just (__ )));
42
+ assertThat (just (7 ).zip (nothing ()), equalTo (__ ));
43
43
// Explicit types help the compiler
44
44
assertThat (Maybe .<Integer >nothing ().zip (just (inc )), equalTo (__ ));
45
45
@@ -50,7 +50,7 @@ public void applicativesZipEmbeddedValuesWithEmbeddedFunctions() {
50
50
51
51
// Moving on to LambdaIterables, where "zipping" is more obvious
52
52
LambdaIterable <Integer > oneThroughThree = LambdaIterable .wrap (asList (1 , 2 , 3 ));
53
- Applicative <Fn1 <? super Integer , ? extends Integer >, LambdaIterable <? >> wrappedInc = LambdaIterable .wrap (asList (inc ));
53
+ LambdaIterable <Fn1 <? super Integer , ? extends Integer >> wrappedInc = LambdaIterable .wrap (asList (inc ));
54
54
assertThat (oneThroughThree .zip (wrappedInc ).unwrap (), iterates (2 , 3 , 4 ));
55
55
56
56
Fn1 <Integer , Integer > dec = x -> x - 1 ;
@@ -62,6 +62,30 @@ public void applicativesZipEmbeddedValuesWithEmbeddedFunctions() {
62
62
assertThat (oneThroughThree .zip (allFunctions ).unwrap (), iterates (__ ()));
63
63
}
64
64
65
+ @ Test
66
+ public void functionIsApplicative () {
67
+ Fn1 <String , Integer > strLen = String ::length ;
68
+ Fn1 <String , String > toUpper = String ::toUpperCase ;
69
+
70
+ // Result of unary function calls are passed to mapping function as arguments
71
+ Fn1 <String , Tuple2 <Integer , String >> lengthAndUppercase = LiftA2 .liftA2 (Tuple2 ::tuple , strLen , toUpper );
72
+ assertThat (lengthAndUppercase .apply ("hello world" ), equalTo (tuple (11 , "HELLO WORLD" )));
73
+
74
+ Fn1 <Integer , Integer > mod3 = i -> i % 3 ;
75
+ Fn1 <Integer , Integer > div3 = i -> i / 3 ;
76
+
77
+ Fn1 <Integer , String > showDivision = LiftA2 .liftA2 ((divided , remainder ) -> String .format ("%d * 3 + %d" , divided , remainder ), div3 , mod3 );
78
+ assertThat (showDivision .apply (10 ), equalTo (__ ));
79
+
80
+
81
+ Fn1 <String , Integer > findStart = s -> s .indexOf ('j' );
82
+ Fn1 <String , Integer > findEnd = s -> s .indexOf (' ' );
83
+ Fn3 <String , Integer , Integer , String > cutString = String ::substring ;
84
+
85
+ Fn1 <String , String > transformAndCut = LiftA3 .liftA3 (cutString , toUpper , findStart , findEnd );
86
+ assertThat (transformAndCut .apply ("hellojava world" ), equalTo (__ ));
87
+ }
88
+
65
89
@ Test
66
90
public void lazyApplicatives () {
67
91
// Zipping LambdaIterables is lazy because LambdaIterables are lazy
@@ -85,44 +109,21 @@ public void lazyApplicatives() {
85
109
Lazy <Maybe <Fn1 <? super Integer , ? extends String >>> lazyGetToString = lazy (() ->
86
110
expensiveWayToGetMaybeToString .apply (100_000_000 ));
87
111
88
- // ...then apply it with lazyZip
112
+ // ...then apply it with lazyZip.
89
113
Maybe <Integer > nothing = nothing ();
114
+ // Note: unlike LambdaIterables, the Maybe inside is not itself lazy
90
115
Lazy <Maybe <String >> lazyNothingToString = nothing .lazyZip (lazyGetToString );
91
116
92
117
assertThat (lazyNothingToString .value (), equalTo (__ ));
93
118
assertThat (computed .get (), equalTo (__ ));
94
119
95
- // zip, however, we've eagerly generated a mapping function
120
+ // zip, however, eagerly generates a mapping function
96
121
Maybe <String > nothingToString = nothing .zip (expensiveWayToGetMaybeToString .apply (100_000 ));
97
122
assertThat (nothingToString , equalTo (__ ));
98
123
assertThat (computed .get (), equalTo (__ ));
99
124
}
100
125
101
- @ Test
102
- public void functionIsApplicative () {
103
- Fn1 <String , Integer > strLen = String ::length ;
104
- Fn1 <String , String > toUpper = String ::toUpperCase ;
105
-
106
- // Result of unary function calls are passed to mapping function as arguments
107
- Fn1 <String , Tuple2 <Integer , String >> lengthAndUppercase = LiftA2 .liftA2 (Tuple2 ::tuple , strLen , toUpper );
108
- assertThat (lengthAndUppercase .apply ("hello world" ), equalTo (tuple (11 , "HELLO WORLD" )));
109
-
110
- Fn1 <Integer , Integer > mod3 = i -> i % 3 ;
111
- Fn1 <Integer , Integer > div3 = i -> i / 3 ;
112
-
113
- Fn1 <Integer , String > showDivision = LiftA2 .liftA2 ((divided , remainder ) -> String .format ("%d * 3 + %d" , divided , remainder ), div3 , mod3 );
114
- assertThat (showDivision .apply (10 ), equalTo (__ ));
115
-
116
-
117
- Fn1 <String , Integer > findStart = s -> s .indexOf ('j' );
118
- Fn1 <String , Integer > findEnd = s -> s .indexOf (' ' );
119
- Fn3 <String , Integer , Integer , String > cutString = String ::substring ;
120
-
121
- Fn1 <String , String > transformAndCut = LiftA3 .liftA3 (cutString , toUpper , findStart , findEnd );
122
- assertThat (transformAndCut .apply ("hellojava world" ), equalTo (__ ));
123
- }
124
-
125
- @ Test
126
+ @ Test (timeout = 6500 )
126
127
public void applicativeRepresentsParallelism () throws ExecutionException , InterruptedException {
127
128
IO <Integer > foo = IO .io (() -> {
128
129
Thread .sleep (2_000 );
@@ -149,7 +150,8 @@ public void applicativeRepresentsParallelism() throws ExecutionException, Interr
149
150
150
151
applicativeInIo
151
152
.flatMap (result -> IO .io (() -> assertThat (result , equalTo (__ ))))
152
- .unsafePerformAsyncIO (Executors .newFixedThreadPool (2 ))
153
+ // How many threads should we use?
154
+ .unsafePerformAsyncIO (Executors .newFixedThreadPool (__ ()))
153
155
.get ();
154
156
155
157
System .out .printf ("Multiple thread execution took %d seconds%n" , (System .currentTimeMillis () - multipleThreadStart ) / 1000 );
0 commit comments