Skip to content

Commit bd3c4c6

Browse files
committed
Merge pull request #166 from mperry/issue162
Fixes #162, fix Validation.sequence and rename to sequenceReduce
2 parents a51c874 + dacb232 commit bd3c4c6

File tree

2 files changed

+32
-17
lines changed

2 files changed

+32
-17
lines changed

core/src/main/java/fj/data/Validation.java

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -801,19 +801,19 @@ public <B, C, D> Validation<List<E>, D> accumulate(Validation<E, B> v2, Validati
801801
}
802802
}
803803

804-
805-
806-
public static <A, E> Validation<List<E>, List<A>> sequence(List<Validation<E, A>> list) {
807-
F2<Validation<E, A>, Validation<List<E>, List<A>>, Validation<List<E>, List<A>>> f2 = (v, acc) -> {
808-
if (acc.isFail() && v.isFail()) {
809-
return Validation.validation(acc.toEither().left().map(l -> l.cons(v.fail())));
810-
} else if (acc.isSuccess() && v.isSuccess()) {
811-
return acc.map(l -> l.cons(v.success()));
812-
} else {
813-
return acc;
814-
}
815-
};
816-
return list.foldRight(f2, Validation.success(List.nil()));
804+
/**
805+
* If the list contains a failure, returns a Validation of the fails in the
806+
* list, otherwise returns a successful Validation with the list of
807+
* successful values.
808+
*/
809+
public static <A, E> Validation<List<E>, List<A>> sequenceReduce(List<Validation<E, A>> list) {
810+
if (list.exists(v -> v.isFail())) {
811+
F2<List<E>, Validation<E, A>, List<E>> f = (acc, v) -> acc.cons(v.fail());
812+
return Validation.fail(list.filter(v -> v.isFail()).foldLeft(f, List.nil()).reverse());
813+
} else {
814+
F2<List<A>, Validation<E, A>, List<A>> f = (acc, v) -> acc.cons(v.success());
815+
return Validation.success(list.filter(v -> v.isSuccess()).foldLeft(f, List.nil()).reverse());
816+
}
817817
}
818818

819819
public <C> List<Validation<E, C>> traverseList(F<T, List<C>> f){

props-core/src/test/java/fj/data/properties/ValidationProperties.java

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,12 @@
55
import fj.data.Validation;
66
import fj.test.Arbitrary;
77
import fj.test.Property;
8-
import fj.test.reflect.CheckParams;
98
import fj.test.runner.PropertyTestRunner;
10-
import org.junit.Assert;
11-
import org.junit.Test;
129
import org.junit.runner.RunWith;
1310

1411
import static fj.test.Arbitrary.*;
12+
import static fj.test.Property.implies;
13+
import static fj.test.Property.prop;
1514

1615
/**
1716
* Created by MarkPerry on 3/07/2015.
@@ -26,7 +25,23 @@ public Property partition() {
2625
boolean b1 = p._1().length() + p._2().length() == list.length();
2726
boolean b2 = p._1().map(s -> Validation.<String, Integer>fail(s)).equals(list.filter(v -> v.isFail()));
2827
boolean b3 = p._2().map(s -> Validation.<String, Integer>success(s)).equals(list.filter(v -> v.isSuccess()));
29-
return Property.prop(b1 && b2 && b3);
28+
return prop(b1 && b2 && b3);
29+
});
30+
}
31+
32+
public Property sequenceReduce() {
33+
Arbitrary<List<Validation<String, Integer>>> al = arbList(arbValidation(arbUSASCIIString, arbInteger));
34+
return Property.property(al, list -> {
35+
Validation<List<String>, List<Integer>> v = Validation.sequenceReduce(list);
36+
Property p1 = implies(
37+
list.exists(v1 -> v1.isFail()),
38+
() -> prop(v.fail().equals(list.filter(v2 -> v2.isFail()).map(v2 -> v2.fail())))
39+
);
40+
Property p2 = implies(
41+
list.forall(v1 -> v1.isSuccess()),
42+
() -> prop(v.success().equals(list.filter(v2 -> v2.isSuccess()).map(v2 -> v2.success())))
43+
);
44+
return p1.and(p2);
3045
});
3146
}
3247

0 commit comments

Comments
 (0)