|
1 | 1 | package fj.data; |
2 | 2 |
|
3 | 3 | import fj.*; |
| 4 | +import fj.control.Trampoline; |
4 | 5 | import fj.function.Effect1; |
5 | 6 |
|
6 | | -import static fj.Function.curry; |
7 | | -import static fj.P.p; |
| 7 | +import java.util.Iterator; |
8 | 8 |
|
9 | | -import static fj.Unit.unit; |
10 | 9 | import static fj.Bottom.error; |
| 10 | +import static fj.Function.*; |
| 11 | +import static fj.P.p; |
| 12 | +import static fj.Unit.unit; |
| 13 | +import static fj.data.Either.*; |
11 | 14 | import static fj.data.List.list; |
12 | 15 |
|
13 | | -import java.util.Iterator; |
14 | | - |
15 | 16 | /** |
16 | 17 | * Isomorphic to {@link Either} but has renamed functions and represents failure on the left and success on the right. |
17 | 18 | * This type also has accumulating functions that accept a {@link Semigroup} for binding computation while keeping error |
@@ -825,44 +826,327 @@ public static <A, E> Validation<List<E>, List<A>> sequenceNonCumulative(List<Val |
825 | 826 | } |
826 | 827 | } |
827 | 828 |
|
828 | | - public final <C> List<Validation<E, C>> traverseList(F<T, List<C>> f){ |
829 | | - return isSuccess() ? |
830 | | - f.f(success()).map(Validation::success) : |
831 | | - List.iterableList(fail(e.left().value())); |
832 | | - } |
| 829 | + /** |
| 830 | + * Sequence the given validation and collect the output on the left side of an either. |
| 831 | + * |
| 832 | + * @param validation the given validation |
| 833 | + * @param <E> the type of the failure value |
| 834 | + * @param <R> the type of the right value |
| 835 | + * @param <C> the type of the left value |
| 836 | + * @return the either |
| 837 | + */ |
| 838 | + public static final <E, R, C> Either<Validation<E, C>, R> sequenceEitherLeft(final Validation<E, Either<C, R>> validation) { |
| 839 | + return validation.traverseEitherLeft(identity()); |
| 840 | + } |
833 | 841 |
|
834 | | - public final <C> Stream<Validation<E, C>> traverseStream(F<T, Stream<C>> f){ |
835 | | - return isSuccess() ? |
836 | | - f.f(success()).map(Validation::success) : |
837 | | - Stream.iterableStream(fail(e.left().value())); |
838 | | - } |
| 842 | + /** |
| 843 | + * Sequence the given validation and collect the output on the right side of an either. |
| 844 | + * |
| 845 | + * @param validation the given validation |
| 846 | + * @param <E> the type of the failure value |
| 847 | + * @param <C> the type of the right value |
| 848 | + * @param <L> the type of the left value |
| 849 | + * @return the either |
| 850 | + */ |
| 851 | + public static final <E, L, C> Either<L, Validation<E, C>> sequenceEitherRight(final Validation<E, Either<L, C>> validation) { |
| 852 | + return validation.traverseEitherRight(identity()); |
| 853 | + } |
839 | 854 |
|
840 | | - public final <C> Option<Validation<E, C>> traverseOption(F<T, Option<C>> f){ |
841 | | - return isSuccess() ? |
842 | | - f.f(success()).map(Validation::success) : |
843 | | - Option.some(fail(e.left().value())); |
844 | | - } |
| 855 | + /** |
| 856 | + * Sequence the given validation and collect the output as a function. |
| 857 | + * |
| 858 | + * @param validation the given validation |
| 859 | + * @param <E> the type of the failure value |
| 860 | + * @param <C> the type of input value |
| 861 | + * @param <B> the type of output value |
| 862 | + * @return the function |
| 863 | + */ |
| 864 | + public static final <E, C, B> F<C, Validation<E, B>> sequenceF(final Validation<E, F<C, B>> validation) { |
| 865 | + return validation.traverseF(identity()); |
| 866 | + } |
845 | 867 |
|
846 | | - public final <C> IO<Validation<E, C>> traverseIO(F<T, IO<C>> f){ |
847 | | - return isSuccess() ? |
848 | | - IOFunctions.map(f.f(success()), Validation::success) : |
849 | | - IOFunctions.unit(fail(e.left().value())); |
850 | | - } |
| 868 | + /** |
| 869 | + * Sequence the given validation and collect the output as an IO. |
| 870 | + * |
| 871 | + * @param validation the given validation |
| 872 | + * @param <E> the type of the failure value |
| 873 | + * @param <C> the type of the IO value |
| 874 | + * @return the IO |
| 875 | + */ |
| 876 | + public static final <E, C> IO<Validation<E, C>> sequenceIO(final Validation<E, IO<C>> validation) { |
| 877 | + return validation.traverseIO(identity()); |
| 878 | + } |
851 | 879 |
|
852 | | - public final <C> P1<Validation<E, C>> traverseP1(F<T, P1<C>> f){ |
853 | | - return isSuccess() ? |
854 | | - f.f(success()).map(Validation::success) : |
855 | | - p(fail(e.left().value())); |
856 | | - } |
| 880 | + /** |
| 881 | + * Sequence the given validation and collect the output as a list. |
| 882 | + * |
| 883 | + * @param validation the given validation |
| 884 | + * @param <E> the type of the failure value |
| 885 | + * @param <C> the type of the list value |
| 886 | + * @return the list |
| 887 | + */ |
| 888 | + public static final <E, C> List<Validation<E, C>> sequenceList(final Validation<E, List<C>> validation) { |
| 889 | + return validation.traverseList(identity()); |
| 890 | + } |
| 891 | + |
| 892 | + /** |
| 893 | + * Sequence the given validation and collect the output as an option. |
| 894 | + * |
| 895 | + * @param validation the given validation |
| 896 | + * @param <E> the type of the failure value |
| 897 | + * @param <C> the type of the option value |
| 898 | + * @return the option |
| 899 | + */ |
| 900 | + public static final <E, C> Option<Validation<E, C>> sequenceOption(final Validation<E, Option<C>> validation) { |
| 901 | + return validation.traverseOption(identity()); |
| 902 | + } |
857 | 903 |
|
| 904 | + /** |
| 905 | + * Sequence the given validation and collect the output as a P1. |
| 906 | + * |
| 907 | + * @param validation the given validation |
| 908 | + * @param <E> the type of the failure value |
| 909 | + * @param <C> the type of the P1 value |
| 910 | + * @return the P1 |
| 911 | + */ |
| 912 | + public static final <E, C> P1<Validation<E, C>> sequenceP1(final Validation<E, P1<C>> validation) { |
| 913 | + return validation.traverseP1(identity()); |
| 914 | + } |
858 | 915 |
|
859 | | - public static <A, E> List<E> fails(List<Validation<E, ?>> list) { |
860 | | - return list.filter(Validation::isFail).map(v -> v.fail()); |
861 | | - } |
| 916 | + /** |
| 917 | + * Sequence the given validation and collect the output as a seq. |
| 918 | + * |
| 919 | + * @param validation the given validation |
| 920 | + * @param <E> the type of the failure value |
| 921 | + * @param <C> the type of the seq value |
| 922 | + * @return the seq |
| 923 | + */ |
| 924 | + public static final <E, C> Seq<Validation<E, C>> sequenceSeq(final Validation<E, Seq<C>> validation) { |
| 925 | + return validation.traverseSeq(identity()); |
| 926 | + } |
862 | 927 |
|
863 | | - public static <A, E> List<A> successes(List<Validation<?, A>> list) { |
864 | | - return list.filter(Validation::isSuccess).map(v -> v.success()); |
865 | | - } |
| 928 | + /** |
| 929 | + * Sequence the given validation and collect the output as a set. |
| 930 | + * |
| 931 | + * @param ordE the given failure value ord |
| 932 | + * @param ordC the given success value ord |
| 933 | + * @param validation the given validation |
| 934 | + * @param <E> the type of the failure value |
| 935 | + * @param <C> the type of the set value |
| 936 | + * @return the set |
| 937 | + */ |
| 938 | + public static final <E, C> Set<Validation<E, C>> sequenceSet(final Ord<E> ordE, final Ord<C> ordC, final Validation<E, Set<C>> validation) { |
| 939 | + return validation.traverseSet(ordE, ordC, identity()); |
| 940 | + } |
| 941 | + |
| 942 | + /** |
| 943 | + * Sequence the given validation and collect the output as a stream. |
| 944 | + * |
| 945 | + * @param validation the given validation |
| 946 | + * @param <E> the type of the failure value |
| 947 | + * @param <C> the type of the stream value |
| 948 | + * @return the stream |
| 949 | + */ |
| 950 | + public static final <E, C> Stream<Validation<E, C>> sequenceStream(final Validation<E, Stream<C>> validation) { |
| 951 | + return validation.traverseStream(identity()); |
| 952 | + } |
| 953 | + |
| 954 | + /** |
| 955 | + * Sequence the given validation and collect the output as a trampoline. |
| 956 | + * |
| 957 | + * @param validation the given validation |
| 958 | + * @param <E> the type of the failure value |
| 959 | + * @param <C> the type of the trampoline value |
| 960 | + * @return the trampoline |
| 961 | + */ |
| 962 | + public static final <E, C> Trampoline<Validation<E, C>> sequenceTrampoline(final Validation<E, Trampoline<C>> validation) { |
| 963 | + return validation.traverseTrampoline(identity()); |
| 964 | + } |
| 965 | + |
| 966 | + /** |
| 967 | + * Sequence the given validation and collect the output as a validation. |
| 968 | + * |
| 969 | + * @param validation the given validation |
| 970 | + * @param <E> the type of the failure value |
| 971 | + * @param <E1> the type of the failure value |
| 972 | + * @param <C> the type of the success value |
| 973 | + * @return the validation |
| 974 | + */ |
| 975 | + public static final <E, E1, C> Validation<E1, Validation<E, C>> sequenceValidation(final Validation<E, Validation<E1, C>> validation) { |
| 976 | + return validation.traverseValidation(identity()); |
| 977 | + } |
| 978 | + |
| 979 | + /** |
| 980 | + * Traverse this validation with the given function and collect the output on the left side of an either. |
| 981 | + * |
| 982 | + * @param f the given function |
| 983 | + * @param <C> the type of the left value |
| 984 | + * @param <R> the type of the right value |
| 985 | + * @return the list |
| 986 | + */ |
| 987 | + public final <R, C> Either<Validation<E, C>, R> traverseEitherLeft(final F<T, Either<C, R>> f) { |
| 988 | + return validation( |
| 989 | + failure -> left(fail(failure)), |
| 990 | + success -> f.f(success).left().map(Validation::success)); |
| 991 | + } |
| 992 | + |
| 993 | + /** |
| 994 | + * Traverse this validation with the given function and collect the output on the right side of an either. |
| 995 | + * |
| 996 | + * @param f the given function |
| 997 | + * @param <L> the type of the left value |
| 998 | + * @param <C> the type of the right value |
| 999 | + * @return the list |
| 1000 | + */ |
| 1001 | + public final <L, C> Either<L, Validation<E, C>> traverseEitherRight(final F<T, Either<L, C>> f) { |
| 1002 | + return validation( |
| 1003 | + failure -> right(fail(failure)), |
| 1004 | + success -> f.f(success).right().map(Validation::success)); |
| 1005 | + } |
| 1006 | + |
| 1007 | + /** |
| 1008 | + * Traverse this validation with the given function and collect the output as a function. |
| 1009 | + * |
| 1010 | + * @param f the given function |
| 1011 | + * @param <C> the type of the input value |
| 1012 | + * @param <B> the type of the output value |
| 1013 | + * @return the function |
| 1014 | + */ |
| 1015 | + public final <C, B> F<C, Validation<E, B>> traverseF(final F<T, F<C, B>> f) { |
| 1016 | + return validation( |
| 1017 | + failure -> constant(fail(failure)), |
| 1018 | + success -> andThen(f.f(success), Validation::success)); |
| 1019 | + } |
| 1020 | + |
| 1021 | + /** |
| 1022 | + * Traverse this validation with the given function and collect the output as an IO. |
| 1023 | + * |
| 1024 | + * @param f the given function |
| 1025 | + * @param <C> the type of the IO value |
| 1026 | + * @return the IO |
| 1027 | + */ |
| 1028 | + public final <C> IO<Validation<E, C>> traverseIO(final F<T, IO<C>> f) { |
| 1029 | + return validation( |
| 1030 | + failure -> IOFunctions.unit(fail(failure)), |
| 1031 | + success -> IOFunctions.map(f.f(success), Validation::success)); |
| 1032 | + } |
| 1033 | + |
| 1034 | + /** |
| 1035 | + * Traverse this validation with the given function and collect the output as a list. |
| 1036 | + * |
| 1037 | + * @param f the given function |
| 1038 | + * @param <C> the type of the list value |
| 1039 | + * @return the list |
| 1040 | + */ |
| 1041 | + public final <C> List<Validation<E, C>> traverseList(final F<T, List<C>> f) { |
| 1042 | + return validation( |
| 1043 | + failure -> List.single(fail(failure)), |
| 1044 | + success -> f.f(success).map(Validation::success)); |
| 1045 | + } |
| 1046 | + |
| 1047 | + /** |
| 1048 | + * Traverse this validation with the given function and collect the output as an option. |
| 1049 | + * |
| 1050 | + * @param f the given function |
| 1051 | + * @param <C> the type of the option value |
| 1052 | + * @return the option |
| 1053 | + */ |
| 1054 | + public final <C> Option<Validation<E, C>> traverseOption(F<T, Option<C>> f) { |
| 1055 | + return validation( |
| 1056 | + failure -> Option.some(fail(failure)), |
| 1057 | + success -> f.f(success).map(Validation::success)); |
| 1058 | + } |
| 1059 | + |
| 1060 | + /** |
| 1061 | + * Traverse this validation with the given function and collect the output as a P1. |
| 1062 | + * |
| 1063 | + * @param f the given function |
| 1064 | + * @param <C> the type of the P1 value |
| 1065 | + * @return the P1 |
| 1066 | + */ |
| 1067 | + public final <C> P1<Validation<E, C>> traverseP1(final F<T, P1<C>> f) { |
| 1068 | + return validation( |
| 1069 | + failure -> p(fail(failure)), |
| 1070 | + success -> f.f(success).map(Validation::success)); |
| 1071 | + } |
| 1072 | + |
| 1073 | + /** |
| 1074 | + * Traverse this validation with the given function and collect the output as a seq. |
| 1075 | + * |
| 1076 | + * @param f the given function |
| 1077 | + * @param <C> the type of the seq value |
| 1078 | + * @return the seq |
| 1079 | + */ |
| 1080 | + public final <C> Seq<Validation<E, C>> traverseSeq(final F<T, Seq<C>> f) { |
| 1081 | + return validation( |
| 1082 | + failure -> Seq.single(fail(failure)), |
| 1083 | + success -> f.f(success).map(Validation::success)); |
| 1084 | + } |
| 1085 | + |
| 1086 | + /** |
| 1087 | + * Traverse this validation with the given function and collect the output as a set; use the given success and failure value ords to order the set. |
| 1088 | + * |
| 1089 | + * @param ordE the given failure value ord |
| 1090 | + * @param ordC the given success value ord |
| 1091 | + * @param f the given function |
| 1092 | + * @param <C> the type of the set value |
| 1093 | + * @return the set |
| 1094 | + */ |
| 1095 | + public final <C> Set<Validation<E, C>> traverseSet(final Ord<E> ordE, final Ord<C> ordC, final F<T, Set<C>> f) { |
| 1096 | + final Ord<Validation<E, C>> ord = Ord.validationOrd(ordE, ordC); |
| 1097 | + return validation( |
| 1098 | + failure -> Set.single(ord, fail(failure)), |
| 1099 | + success -> f.f(success).map(ord, Validation::success)); |
| 1100 | + } |
| 1101 | + |
| 1102 | + /** |
| 1103 | + * Traverse this validation with the given function and collect the output as a stream. |
| 1104 | + * |
| 1105 | + * @param f the given function |
| 1106 | + * @param <C> the type of the stream value |
| 1107 | + * @return the stream |
| 1108 | + */ |
| 1109 | + public final <C> Stream<Validation<E, C>> traverseStream(final F<T, Stream<C>> f) { |
| 1110 | + return validation( |
| 1111 | + failure -> Stream.single(fail(failure)), |
| 1112 | + success -> f.f(success).map(Validation::success)); |
| 1113 | + } |
| 1114 | + |
| 1115 | + /** |
| 1116 | + * Traverse this validation with the given function and collect the output as a trampoline. |
| 1117 | + * |
| 1118 | + * @param f the given function |
| 1119 | + * @param <C> the type of the trampoline value |
| 1120 | + * @return the trampoline |
| 1121 | + */ |
| 1122 | + public final <C> Trampoline<Validation<E, C>> traverseTrampoline(final F<T, Trampoline<C>> f) { |
| 1123 | + return validation( |
| 1124 | + failure -> Trampoline.pure(fail(failure)), |
| 1125 | + success -> f.f(success).map(Validation::success)); |
| 1126 | + } |
| 1127 | + |
| 1128 | + /** |
| 1129 | + * Traverse this validation with the given function and collect the output as a validation. |
| 1130 | + * |
| 1131 | + * @param f the given function |
| 1132 | + * @param <E1> the type of the failure value |
| 1133 | + * @param <C> the type of the seq value |
| 1134 | + * @return the validation |
| 1135 | + */ |
| 1136 | + public final <E1, C> Validation<E1, Validation<E, C>> traverseValidation(final F<T, Validation<E1, C>> f) { |
| 1137 | + return validation( |
| 1138 | + failure -> success(fail(failure)), |
| 1139 | + success -> f.f(success).map(Validation::success)); |
| 1140 | + } |
| 1141 | + |
| 1142 | + |
| 1143 | + public static <A, E> List<E> fails(List<Validation<E, ?>> list) { |
| 1144 | + return list.filter(Validation::isFail).map(v -> v.fail()); |
| 1145 | + } |
| 1146 | + |
| 1147 | + public static <A, E> List<A> successes(List<Validation<?, A>> list) { |
| 1148 | + return list.filter(Validation::isSuccess).map(v -> v.success()); |
| 1149 | + } |
866 | 1150 |
|
867 | 1151 | /** |
868 | 1152 | * A failing projection of a validation. |
@@ -1268,7 +1552,7 @@ public static Validation<NumberFormatException, Short> parseShort(final String s |
1268 | 1552 | } |
1269 | 1553 |
|
1270 | 1554 | /** |
1271 | | - * A function that parses a string into a short. |
| 1555 | + * A function that parses a string into a short. |
1272 | 1556 | */ |
1273 | 1557 | public static final F<String, Validation<NumberFormatException, Short>> parseShort = Validation::parseShort; |
1274 | 1558 |
|
|
0 commit comments