001 package fj.data; 002 003 import fj.Effect; 004 import fj.F; 005 import fj.F2; 006 import fj.F3; 007 import fj.F4; 008 import fj.F5; 009 import fj.F6; 010 import fj.F7; 011 import fj.F8; 012 import static fj.Function.curry; 013 import static fj.P.p; 014 import fj.P1; 015 import fj.Unit; 016 import static fj.Unit.unit; 017 import static fj.Bottom.error; 018 import fj.pre.Semigroup; 019 020 import java.util.Iterator; 021 022 /** 023 * Isomorphic to {@link Either} but has renamed functions and represents failure on the left and success on the right. 024 * This type also has accumulating functions that accept a {@link Semigroup} for binding computation while keeping error 025 * values 026 * 027 * @version %build.number%<br> 028 * <ul> 029 * <li>$LastChangedRevision: 163 $</li> 030 * <li>$LastChangedDate: 2009-06-02 03:43:12 +1000 (Tue, 02 Jun 2009) $</li> 031 * </ul> 032 */ 033 public final class Validation<E, T> implements Iterable<T> { 034 private final Either<E, T> e; 035 036 private Validation(final Either<E, T> e) { 037 this.e = e; 038 } 039 040 /** 041 * Returns <code>true</code> if this is a failure, <code>false</code> otherwise. 042 * 043 * @return <code>true</code> if this is a failure, <code>false</code> otherwise. 044 */ 045 public boolean isFail() { 046 return e.isLeft(); 047 } 048 049 /** 050 * Returns <code>true</code> if this is a success, <code>false</code> otherwise. 051 * 052 * @return <code>true</code> if this is a success, <code>false</code> otherwise. 053 */ 054 public boolean isSuccess() { 055 return e.isRight(); 056 } 057 058 /** 059 * Returns the failing value, or throws an error if there is no failing value. 060 * 061 * @return the failing value, or throws an error if there is no failing value. 062 */ 063 public E fail() { 064 if (isFail()) 065 return e.left().value(); 066 else 067 throw error("Validation: fail on success value"); 068 } 069 070 /** 071 * Returns the success value, or throws an error if there is no success value. 072 * 073 * @return the success value, or throws an error if there is no success value. 074 */ 075 public T success() { 076 if (isSuccess()) 077 return e.right().value(); 078 else 079 throw error("Validation: success on fail value"); 080 } 081 082 /** 083 * The catamorphism for validation. Folds over this validation breaking into left or right. 084 * 085 * @param fail The function to call if this failed. 086 * @param success The function to call if this succeeded. 087 * @return The reduced value. 088 */ 089 public <X> X validation(final F<E, X> fail, final F<T, X> success) { 090 return e.either(fail, success); 091 } 092 093 /** 094 * Returns a failing projection of this validation. 095 * 096 * @return a failing projection of this validation. 097 */ 098 public FailProjection<E, T> f() { 099 return new FailProjection<E, T>(this); 100 } 101 102 /** 103 * Returns an either projection of this validation. 104 * 105 * @return An either projection of this validation. 106 */ 107 public Either<E, T> toEither() { 108 return e; 109 } 110 111 /** 112 * Returns the success value or fails with the given error message. 113 * 114 * @param err The error message to fail with. 115 * @return The success value. 116 */ 117 public T successE(final P1<String> err) { 118 return e.right().valueE(err); 119 } 120 121 /** 122 * Returns the success value or fails with the given error message. 123 * 124 * @param err The error message to fail with. 125 * @return The success value. 126 */ 127 public T successE(final String err) { 128 return e.right().valueE(p(err)); 129 } 130 131 /** 132 * Returns the success value or the given value. 133 * 134 * @param t The value to return if this is failure. 135 * @return The success value or the given value. 136 */ 137 public T orSuccess(final P1<T> t) { 138 return e.right().orValue(t); 139 } 140 141 /** 142 * Returns the success value or the given value. 143 * 144 * @param t The value to return if this is failure. 145 * @return The success value or the given value. 146 */ 147 public T orSuccess(final T t) { 148 return e.right().orValue(p(t)); 149 } 150 151 /** 152 * The success value or the application of the given function to the failing value. 153 * 154 * @param f The function to execute on the failing value. 155 * @return The success value or the application of the given function to the failing value. 156 */ 157 public T on(final F<E, T> f) { 158 return e.right().on(f); 159 } 160 161 /** 162 * Executes a side-effect on the success value if there is one. 163 * 164 * @param f The side-effect to execute. 165 * @return The unit value. 166 */ 167 public Unit foreach(final F<T, Unit> f) { 168 return e.right().foreach(f); 169 } 170 171 /** 172 * Executes a side-effect on the success value if there is one. 173 * 174 * @param f The side-effect to execute. 175 */ 176 public void foreach(final Effect<T> f) { 177 e.right().foreach(f); 178 } 179 180 /** 181 * Maps the given function across the success side of this validation. 182 * 183 * @param f The function to map. 184 * @return A new validation with the function mapped. 185 */ 186 @SuppressWarnings({"unchecked"}) 187 public <A> Validation<E, A> map(final F<T, A> f) { 188 return isFail() ? 189 Validation.<E, A>fail(fail()) : 190 Validation.<E, A>success(f.f(success())); 191 } 192 193 /** 194 * Binds the given function across this validation's success value if it has one. 195 * 196 * @param f The function to bind across this validation. 197 * @return A new validation value after binding. 198 */ 199 @SuppressWarnings({"unchecked"}) 200 public <A> Validation<E, A> bind(final F<T, Validation<E, A>> f) { 201 return isSuccess() ? f.f(success()) : Validation.<E, A>fail(fail()); 202 } 203 204 /** 205 * Anonymous bind through this validation. 206 * 207 * @param v The value to bind with. 208 * @return A validation after binding. 209 */ 210 public <A> Validation<E, A> sequence(final Validation<E, A> v) { 211 return bind(fj.Function.<T, Validation<E, A>>constant(v)); 212 } 213 214 /** 215 * Returns <code>None</code> if this is a failure or if the given predicate <code>p</code> does not hold for the 216 * success value, otherwise, returns a success in <code>Some</code>. 217 * 218 * @param f The predicate function to test on this success value. 219 * @return <code>None</code> if this is a failure or if the given predicate <code>p</code> does not hold for the 220 * success value, otherwise, returns a success in <code>Some</code>. 221 */ 222 public <A> Option<Validation<A, T>> filter(final F<T, Boolean> f) { 223 return e.right().<A>filter(f).map(Validation.<A, T>validation()); 224 } 225 226 /** 227 * Function application on the success value. 228 * 229 * @param v The validation of the function to apply on the success value. 230 * @return The result of function application in validation. 231 */ 232 public <A> Validation<E, A> apply(final Validation<E, F<T, A>> v) { 233 return v.bind(new F<F<T, A>, Validation<E, A>>() { 234 public Validation<E, A> f(final F<T, A> f) { 235 return map(f); 236 } 237 }); 238 } 239 240 /** 241 * Returns <code>true</code> if this is a failure or returns the result of the application of the given 242 * function to the success value. 243 * 244 * @param f The predicate function to test on this success value. 245 * @return <code>true</code> if this is a failure or returns the result of the application of the given 246 * function to the success value. 247 */ 248 public boolean forall(final F<T, Boolean> f) { 249 return e.right().forall(f); 250 } 251 252 /** 253 * Returns <code>false</code> if this is a failure or returns the result of the application of the given 254 * function to the success value. 255 * 256 * @param f The predicate function to test on this success value. 257 * @return <code>false</code> if this is a failure or returns the result of the application of the given 258 * function to the success value. 259 */ 260 public boolean exists(final F<T, Boolean> f) { 261 return e.right().exists(f); 262 } 263 264 /** 265 * Returns a single element list if this is a success value, otherwise an empty list. 266 * 267 * @return A single element list if this is a success value, otherwise an empty list. 268 */ 269 public List<T> toList() { 270 return e.right().toList(); 271 } 272 273 /** 274 * Returns the success value in <code>Some</code> if there is one, otherwise <code>None</code>. 275 * 276 * @return The success value in <code>Some</code> if there is one, otherwise <code>None</code>. 277 */ 278 public Option<T> toOption() { 279 return e.right().toOption(); 280 } 281 282 /** 283 * Returns a single element array if this is a success value, otherwise an empty list. 284 * 285 * @return A single element array if this is a success value, otherwise an empty list. 286 */ 287 public Array<T> toArray() { 288 return e.right().toArray(); 289 } 290 291 /** 292 * Returns a single element stream if this is a success value, otherwise an empty list. 293 * 294 * @return A single element stream if this is a success value, otherwise an empty list. 295 */ 296 public Stream<T> toStream() { 297 return e.right().toStream(); 298 } 299 300 /** 301 * Function application on the successful side of this validation, or accumulating the errors on the failing side 302 * using the given semigroup should one or more be encountered. 303 * 304 * @param s The semigroup to accumulate errors with if 305 * @param v The validating function to apply. 306 * @return A failing validation if this or the given validation failed (with errors accumulated if both) or a 307 * succeeding validation if both succeeded. 308 */ 309 @SuppressWarnings({"unchecked"}) 310 public <A> Validation<E, A> accumapply(final Semigroup<E> s, final Validation<E, F<T, A>> v) { 311 return isFail() ? 312 Validation.<E, A>fail(v.isFail() ? 313 s.sum(v.fail(), fail()) : 314 fail()) : 315 v.isFail() ? 316 Validation.<E, A>fail(v.fail()) : 317 Validation.<E, A>success(v.success().f(success())); 318 } 319 320 /** 321 * Accumulates errors on the failing side of this or any given validation if one or more are encountered, or applies 322 * the given function if all succeeded and returns that value on the successful side. 323 * 324 * @param s The semigroup to accumulate errors with if one or more validations fail. 325 * @param va The second validation to accumulate errors with if it failed. 326 * @param f The function to apply if all validations have succeeded. 327 * @return A succeeding validation if all validations succeeded, or a failing validation with errors accumulated if 328 * one or more failed. 329 */ 330 public <A, B> Validation<E, B> accumulate(final Semigroup<E> s, final Validation<E, A> va, final F<T, F<A, B>> f) { 331 return va.accumapply(s, map(f)); 332 } 333 334 /** 335 * Accumulates errors on the failing side of this or any given validation if one or more are encountered, or applies 336 * the given function if all succeeded and returns that value on the successful side. 337 * 338 * @param s The semigroup to accumulate errors with if one or more validations fail. 339 * @param va The second validation to accumulate errors with if it failed. 340 * @param f The function to apply if all validations have succeeded. 341 * @return A succeeding validation if all validations succeeded, or a failing validation with errors accumulated if 342 * one or more failed. 343 */ 344 public <A, B> Validation<E, B> accumulate(final Semigroup<E> s, final Validation<E, A> va, final F2<T, A, B> f) { 345 return va.accumapply(s, map(curry(f))); 346 } 347 348 /** 349 * Accumulates errors anonymously. 350 * 351 * @param s The semigroup to accumulate errors with if one or more validations fail. 352 * @param va The second validation to accumulate errors with if it failed. 353 * @return A <code>Some</code> if one or more validations failed (accumulated with the semigroup), otherwise, 354 * <code>None</code>. 355 */ 356 public <A> Option<E> accumulate(final Semigroup<E> s, final Validation<E, A> va) { 357 return accumulate(s, va, new F2<T, A, Unit>() { 358 public Unit f(final T t, final A a) { 359 return unit(); 360 } 361 }).f().toOption(); 362 } 363 364 /** 365 * Accumulates errors on the failing side of this or any given validation if one or more are encountered, or applies 366 * the given function if all succeeded and returns that value on the successful side. 367 * 368 * @param s The semigroup to accumulate errors with if one or more validations fail. 369 * @param va The second validation to accumulate errors with if it failed. 370 * @param vb The third validation to accumulate errors with if it failed. 371 * @param f The function to apply if all validations have succeeded. 372 * @return A succeeding validation if all validations succeeded, or a failing validation with errors accumulated if 373 * one or more failed. 374 */ 375 public <A, B, C> Validation<E, C> accumulate(final Semigroup<E> s, final Validation<E, A> va, 376 final Validation<E, B> vb, final F<T, F<A, F<B, C>>> f) { 377 return vb.accumapply(s, accumulate(s, va, f)); 378 } 379 380 /** 381 * Accumulates errors on the failing side of this or any given validation if one or more are encountered, or applies 382 * the given function if all succeeded and returns that value on the successful side. 383 * 384 * @param s The semigroup to accumulate errors with if one or more validations fail. 385 * @param va The second validation to accumulate errors with if it failed. 386 * @param vb The third validation to accumulate errors with if it failed. 387 * @param f The function to apply if all validations have succeeded. 388 * @return A succeeding validation if all validations succeeded, or a failing validation with errors accumulated if 389 * one or more failed. 390 */ 391 public <A, B, C> Validation<E, C> accumulate(final Semigroup<E> s, final Validation<E, A> va, 392 final Validation<E, B> vb, final F3<T, A, B, C> f) { 393 return vb.accumapply(s, accumulate(s, va, curry(f))); 394 } 395 396 /** 397 * Accumulates errors anonymously. 398 * 399 * @param s The semigroup to accumulate errors with if one or more validations fail. 400 * @param va The second validation to accumulate errors with if it failed. 401 * @param vb The third validation to accumulate errors with if it failed. 402 * @return A <code>Some</code> if one or more validations failed (accumulated with the semigroup), otherwise, 403 * <code>None</code>. 404 */ 405 public <A, B> Option<E> accumulate(final Semigroup<E> s, final Validation<E, A> va, final Validation<E, B> vb) { 406 return accumulate(s, va, vb, new F3<T, A, B, Unit>() { 407 public Unit f(final T t, final A a, final B b) { 408 return unit(); 409 } 410 }).f().toOption(); 411 } 412 413 /** 414 * Accumulates errors on the failing side of this or any given validation if one or more are encountered, or applies 415 * the given function if all succeeded and returns that value on the successful side. 416 * 417 * @param s The semigroup to accumulate errors with if one or more validations fail. 418 * @param va The second validation to accumulate errors with if it failed. 419 * @param vb The third validation to accumulate errors with if it failed. 420 * @param vc The fourth validation to accumulate errors with if it failed. 421 * @param f The function to apply if all validations have succeeded. 422 * @return A succeeding validation if all validations succeeded, or a failing validation with errors accumulated if 423 * one or more failed. 424 */ 425 public <A, B, C, D> Validation<E, D> accumulate(final Semigroup<E> s, final Validation<E, A> va, 426 final Validation<E, B> vb, final Validation<E, C> vc, 427 final F<T, F<A, F<B, F<C, D>>>> f) { 428 return vc.accumapply(s, accumulate(s, va, vb, f)); 429 } 430 431 /** 432 * Accumulates errors on the failing side of this or any given validation if one or more are encountered, or applies 433 * the given function if all succeeded and returns that value on the successful side. 434 * 435 * @param s The semigroup to accumulate errors with if one or more validations fail. 436 * @param va The second validation to accumulate errors with if it failed. 437 * @param vb The third validation to accumulate errors with if it failed. 438 * @param vc The fourth validation to accumulate errors with if it failed. 439 * @param f The function to apply if all validations have succeeded. 440 * @return A succeeding validation if all validations succeeded, or a failing validation with errors accumulated if 441 * one or more failed. 442 */ 443 public <A, B, C, D> Validation<E, D> accumulate(final Semigroup<E> s, final Validation<E, A> va, 444 final Validation<E, B> vb, final Validation<E, C> vc, 445 final F4<T, A, B, C, D> f) { 446 return vc.accumapply(s, accumulate(s, va, vb, curry(f))); 447 } 448 449 /** 450 * Accumulates errors anonymously. 451 * 452 * @param s The semigroup to accumulate errors with if one or more validations fail. 453 * @param va The second validation to accumulate errors with if it failed. 454 * @param vb The third validation to accumulate errors with if it failed. 455 * @param vc The fourth validation to accumulate errors with if it failed. 456 * @return A <code>Some</code> if one or more validations failed (accumulated with the semigroup), otherwise, 457 * <code>None</code>. 458 */ 459 public <A, B, C> Option<E> accumulate(final Semigroup<E> s, final Validation<E, A> va, final Validation<E, B> vb, 460 final Validation<E, C> vc) { 461 return accumulate(s, va, vb, vc, new F4<T, A, B, C, Unit>() { 462 public Unit f(final T t, final A a, final B b, final C c) { 463 return unit(); 464 } 465 }).f().toOption(); 466 } 467 468 /** 469 * Accumulates errors on the failing side of this or any given validation if one or more are encountered, or applies 470 * the given function if all succeeded and returns that value on the successful side. 471 * 472 * @param s The semigroup to accumulate errors with if one or more validations fail. 473 * @param va The second validation to accumulate errors with if it failed. 474 * @param vb The third validation to accumulate errors with if it failed. 475 * @param vc The fourth validation to accumulate errors with if it failed. 476 * @param vd The fifth validation to accumulate errors with if it failed. 477 * @param f The function to apply if all validations have succeeded. 478 * @return A succeeding validation if all validations succeeded, or a failing validation with errors accumulated if 479 * one or more failed. 480 */ 481 public <A, B, C, D, E$> Validation<E, E$> accumulate(final Semigroup<E> s, final Validation<E, A> va, 482 final Validation<E, B> vb, final Validation<E, C> vc, 483 final Validation<E, D> vd, 484 final F<T, F<A, F<B, F<C, F<D, E$>>>>> f) { 485 return vd.accumapply(s, accumulate(s, va, vb, vc, f)); 486 } 487 488 /** 489 * Accumulates errors on the failing side of this or any given validation if one or more are encountered, or applies 490 * the given function if all succeeded and returns that value on the successful side. 491 * 492 * @param s The semigroup to accumulate errors with if one or more validations fail. 493 * @param va The second validation to accumulate errors with if it failed. 494 * @param vb The third validation to accumulate errors with if it failed. 495 * @param vc The fourth validation to accumulate errors with if it failed. 496 * @param vd The fifth validation to accumulate errors with if it failed. 497 * @param f The function to apply if all validations have succeeded. 498 * @return A succeeding validation if all validations succeeded, or a failing validation with errors accumulated if 499 * one or more failed. 500 */ 501 public <A, B, C, D, E$> Validation<E, E$> accumulate(final Semigroup<E> s, final Validation<E, A> va, 502 final Validation<E, B> vb, final Validation<E, C> vc, 503 final Validation<E, D> vd, final F5<T, A, B, C, D, E$> f) { 504 return vd.accumapply(s, accumulate(s, va, vb, vc, curry(f))); 505 } 506 507 /** 508 * Accumulates errors anonymously. 509 * 510 * @param s The semigroup to accumulate errors with if one or more validations fail. 511 * @param va The second validation to accumulate errors with if it failed. 512 * @param vb The third validation to accumulate errors with if it failed. 513 * @param vc The fourth validation to accumulate errors with if it failed. 514 * @param vd The fifth validation to accumulate errors with if it failed. 515 * @return A <code>Some</code> if one or more validations failed (accumulated with the semigroup), otherwise, 516 * <code>None</code>. 517 */ 518 public <A, B, C, D> Option<E> accumulate(final Semigroup<E> s, final Validation<E, A> va, final Validation<E, B> vb, 519 final Validation<E, C> vc, final Validation<E, D> vd) { 520 return accumulate(s, va, vb, vc, vd, new F5<T, A, B, C, D, Unit>() { 521 public Unit f(final T t, final A a, final B b, final C c, final D d) { 522 return unit(); 523 } 524 }).f().toOption(); 525 } 526 527 /** 528 * Accumulates errors on the failing side of this or any given validation if one or more are encountered, or applies 529 * the given function if all succeeded and returns that value on the successful side. 530 * 531 * @param s The semigroup to accumulate errors with if one or more validations fail. 532 * @param va The second validation to accumulate errors with if it failed. 533 * @param vb The third validation to accumulate errors with if it failed. 534 * @param vc The fourth validation to accumulate errors with if it failed. 535 * @param vd The fifth validation to accumulate errors with if it failed. 536 * @param ve The sixth validation to accumulate errors with if it failed. 537 * @param f The function to apply if all validations have succeeded. 538 * @return A succeeding validation if all validations succeeded, or a failing validation with errors accumulated if 539 * one or more failed. 540 */ 541 public <A, B, C, D, E$, F$> Validation<E, F$> accumulate(final Semigroup<E> s, final Validation<E, A> va, 542 final Validation<E, B> vb, final Validation<E, C> vc, 543 final Validation<E, D> vd, final Validation<E, E$> ve, 544 final F<T, F<A, F<B, F<C, F<D, F<E$, F$>>>>>> f) { 545 return ve.accumapply(s, accumulate(s, va, vb, vc, vd, f)); 546 } 547 548 /** 549 * Accumulates errors on the failing side of this or any given validation if one or more are encountered, or applies 550 * the given function if all succeeded and returns that value on the successful side. 551 * 552 * @param s The semigroup to accumulate errors with if one or more validations fail. 553 * @param va The second validation to accumulate errors with if it failed. 554 * @param vb The third validation to accumulate errors with if it failed. 555 * @param vc The fourth validation to accumulate errors with if it failed. 556 * @param vd The fifth validation to accumulate errors with if it failed. 557 * @param ve The sixth validation to accumulate errors with if it failed. 558 * @param f The function to apply if all validations have succeeded. 559 * @return A succeeding validation if all validations succeeded, or a failing validation with errors accumulated if 560 * one or more failed. 561 */ 562 public <A, B, C, D, E$, F$> Validation<E, F$> accumulate(final Semigroup<E> s, final Validation<E, A> va, 563 final Validation<E, B> vb, final Validation<E, C> vc, 564 final Validation<E, D> vd, final Validation<E, E$> ve, 565 final F6<T, A, B, C, D, E$, F$> f) { 566 return ve.accumapply(s, accumulate(s, va, vb, vc, vd, curry(f))); 567 } 568 569 /** 570 * Accumulates errors anonymously. 571 * 572 * @param s The semigroup to accumulate errors with if one or more validations fail. 573 * @param va The second validation to accumulate errors with if it failed. 574 * @param vb The third validation to accumulate errors with if it failed. 575 * @param vc The fourth validation to accumulate errors with if it failed. 576 * @param vd The fifth validation to accumulate errors with if it failed. 577 * @param ve The sixth validation to accumulate errors with if it failed. 578 * @return A <code>Some</code> if one or more validations failed (accumulated with the semigroup), otherwise, 579 * <code>None</code>. 580 */ 581 public <A, B, C, D, E$> Option<E> accumulate(final Semigroup<E> s, final Validation<E, A> va, 582 final Validation<E, B> vb, final Validation<E, C> vc, 583 final Validation<E, D> vd, final Validation<E, E$> ve) { 584 return accumulate(s, va, vb, vc, vd, ve, new F6<T, A, B, C, D, E$, Unit>() { 585 public Unit f(final T t, final A a, final B b, final C c, final D d, final E$ e) { 586 return unit(); 587 } 588 }).f().toOption(); 589 } 590 591 /** 592 * Accumulates errors on the failing side of this or any given validation if one or more are encountered, or applies 593 * the given function if all succeeded and returns that value on the successful side. 594 * 595 * @param s The semigroup to accumulate errors with if one or more validations fail. 596 * @param va The second validation to accumulate errors with if it failed. 597 * @param vb The third validation to accumulate errors with if it failed. 598 * @param vc The fourth validation to accumulate errors with if it failed. 599 * @param vd The fifth validation to accumulate errors with if it failed. 600 * @param ve The sixth validation to accumulate errors with if it failed. 601 * @param vf The seventh validation to accumulate errors with if it failed. 602 * @param f The function to apply if all validations have succeeded. 603 * @return A succeeding validation if all validations succeeded, or a failing validation with errors accumulated if 604 * one or more failed. 605 */ 606 public <A, B, C, D, E$, F$, G> Validation<E, G> accumulate(final Semigroup<E> s, final Validation<E, A> va, 607 final Validation<E, B> vb, final Validation<E, C> vc, 608 final Validation<E, D> vd, final Validation<E, E$> ve, 609 final Validation<E, F$> vf, 610 final F<T, F<A, F<B, F<C, F<D, F<E$, F<F$, G>>>>>>> f) { 611 return vf.accumapply(s, accumulate(s, va, vb, vc, vd, ve, f)); 612 } 613 614 /** 615 * Accumulates errors on the failing side of this or any given validation if one or more are encountered, or applies 616 * the given function if all succeeded and returns that value on the successful side. 617 * 618 * @param s The semigroup to accumulate errors with if one or more validations fail. 619 * @param va The second validation to accumulate errors with if it failed. 620 * @param vb The third validation to accumulate errors with if it failed. 621 * @param vc The fourth validation to accumulate errors with if it failed. 622 * @param vd The fifth validation to accumulate errors with if it failed. 623 * @param ve The sixth validation to accumulate errors with if it failed. 624 * @param vf The seventh validation to accumulate errors with if it failed. 625 * @param f The function to apply if all validations have succeeded. 626 * @return A succeeding validation if all validations succeeded, or a failing validation with errors accumulated if 627 * one or more failed. 628 */ 629 public <A, B, C, D, E$, F$, G> Validation<E, G> accumulate(final Semigroup<E> s, final Validation<E, A> va, 630 final Validation<E, B> vb, final Validation<E, C> vc, 631 final Validation<E, D> vd, final Validation<E, E$> ve, 632 final Validation<E, F$> vf, 633 final F7<T, A, B, C, D, E$, F$, G> f) { 634 return vf.accumapply(s, accumulate(s, va, vb, vc, vd, ve, curry(f))); 635 } 636 637 /** 638 * Accumulates errors anonymously. 639 * 640 * @param s The semigroup to accumulate errors with if one or more validations fail. 641 * @param va The second validation to accumulate errors with if it failed. 642 * @param vb The third validation to accumulate errors with if it failed. 643 * @param vc The fourth validation to accumulate errors with if it failed. 644 * @param vd The fifth validation to accumulate errors with if it failed. 645 * @param ve The sixth validation to accumulate errors with if it failed. 646 * @param vf The seventh validation to accumulate errors with if it failed. 647 * @return A <code>Some</code> if one or more validations failed (accumulated with the semigroup), otherwise, 648 * <code>None</code>. 649 */ 650 public <A, B, C, D, E$, F$> Option<E> accumulate(final Semigroup<E> s, final Validation<E, A> va, 651 final Validation<E, B> vb, final Validation<E, C> vc, 652 final Validation<E, D> vd, final Validation<E, E$> ve, 653 final Validation<E, F$> vf) { 654 return accumulate(s, va, vb, vc, vd, ve, vf, new F7<T, A, B, C, D, E$, F$, Unit>() { 655 public Unit f(final T t, final A a, final B b, final C c, final D d, final E$ e, final F$ f) { 656 return unit(); 657 } 658 }).f().toOption(); 659 } 660 661 /** 662 * Accumulates errors on the failing side of this or any given validation if one or more are encountered, or applies 663 * the given function if all succeeded and returns that value on the successful side. 664 * 665 * @param s The semigroup to accumulate errors with if one or more validations fail. 666 * @param va The second validation to accumulate errors with if it failed. 667 * @param vb The third validation to accumulate errors with if it failed. 668 * @param vc The fourth validation to accumulate errors with if it failed. 669 * @param vd The fifth validation to accumulate errors with if it failed. 670 * @param ve The sixth validation to accumulate errors with if it failed. 671 * @param vf The seventh validation to accumulate errors with if it failed. 672 * @param vg The eighth validation to accumulate errors with if it failed. 673 * @param f The function to apply if all validations have succeeded. 674 * @return A succeeding validation if all validations succeeded, or a failing validation with errors accumulated if 675 * one or more failed. 676 */ 677 public <A, B, C, D, E$, F$, G, H> Validation<E, H> accumulate(final Semigroup<E> s, final Validation<E, A> va, 678 final Validation<E, B> vb, final Validation<E, C> vc, 679 final Validation<E, D> vd, final Validation<E, E$> ve, 680 final Validation<E, F$> vf, final Validation<E, G> vg, 681 final F<T, F<A, F<B, F<C, F<D, F<E$, F<F$, F<G, H>>>>>>>> f) { 682 return vg.accumapply(s, accumulate(s, va, vb, vc, vd, ve, vf, f)); 683 } 684 685 /** 686 * Accumulates errors on the failing side of this or any given validation if one or more are encountered, or applies 687 * the given function if all succeeded and returns that value on the successful side. 688 * 689 * @param s The semigroup to accumulate errors with if one or more validations fail. 690 * @param va The second validation to accumulate errors with if it failed. 691 * @param vb The third validation to accumulate errors with if it failed. 692 * @param vc The fourth validation to accumulate errors with if it failed. 693 * @param vd The fifth validation to accumulate errors with if it failed. 694 * @param ve The sixth validation to accumulate errors with if it failed. 695 * @param vf The seventh validation to accumulate errors with if it failed. 696 * @param vg The eighth validation to accumulate errors with if it failed. 697 * @param f The function to apply if all validations have succeeded. 698 * @return A succeeding validation if all validations succeeded, or a failing validation with errors accumulated if 699 * one or more failed. 700 */ 701 public <A, B, C, D, E$, F$, G, H> Validation<E, H> accumulate(final Semigroup<E> s, final Validation<E, A> va, 702 final Validation<E, B> vb, final Validation<E, C> vc, 703 final Validation<E, D> vd, final Validation<E, E$> ve, 704 final Validation<E, F$> vf, final Validation<E, G> vg, 705 final F8<T, A, B, C, D, E$, F$, G, H> f) { 706 return vg.accumapply(s, accumulate(s, va, vb, vc, vd, ve, vf, curry(f))); 707 } 708 709 /** 710 * Accumulates errors anonymously. 711 * 712 * @param s The semigroup to accumulate errors with if one or more validations fail. 713 * @param va The second validation to accumulate errors with if it failed. 714 * @param vb The third validation to accumulate errors with if it failed. 715 * @param vc The fourth validation to accumulate errors with if it failed. 716 * @param vd The fifth validation to accumulate errors with if it failed. 717 * @param ve The sixth validation to accumulate errors with if it failed. 718 * @param vf The seventh validation to accumulate errors with if it failed. 719 * @param vg The eighth validation to accumulate errors with if it failed. 720 * @return A <code>Some</code> if one or more validations failed (accumulated with the semigroup), otherwise, 721 * <code>None</code>. 722 */ 723 public <A, B, C, D, E$, F$, G> Option<E> accumulate(final Semigroup<E> s, final Validation<E, A> va, 724 final Validation<E, B> vb, final Validation<E, C> vc, 725 final Validation<E, D> vd, final Validation<E, E$> ve, 726 final Validation<E, F$> vf, final Validation<E, G> vg) { 727 return accumulate(s, va, vb, vc, vd, ve, vf, vg, new F8<T, A, B, C, D, E$, F$, G, Unit>() { 728 public Unit f(final T t, final A a, final B b, final C c, final D d, final E$ e, final F$ f, final G g) { 729 return unit(); 730 } 731 }).f().toOption(); 732 } 733 734 /** 735 * Returns an iterator for this validation. This method exists to permit the use in a <code>for</code>-each loop. 736 * 737 * @return A iterator for this validation. 738 */ 739 public Iterator<T> iterator() { 740 return toEither().right().iterator(); 741 } 742 743 /** 744 * A failing projection of a validation. 745 */ 746 public final class FailProjection<E, T> implements Iterable<E> { 747 private final Validation<E, T> v; 748 749 private FailProjection(final Validation<E, T> v) { 750 this.v = v; 751 } 752 753 /** 754 * Returns the underlying validation. 755 * 756 * @return The underlying validation. 757 */ 758 public Validation<E, T> validation() { 759 return v; 760 } 761 762 /** 763 * Returns the failing value or fails with the given error message. 764 * 765 * @param err The error message to fail with. 766 * @return The failing value. 767 */ 768 public E failE(final P1<String> err) { 769 return v.toEither().left().valueE(err); 770 } 771 772 /** 773 * Returns the failing value or fails with the given error message. 774 * 775 * @param err The error message to fail with. 776 * @return The failing value. 777 */ 778 public E failE(final String err) { 779 return failE(p(err)); 780 } 781 782 /** 783 * Returns the failing value or the given value. 784 * 785 * @param e The value to return if this is success. 786 * @return The failing value or the given value. 787 */ 788 public E orFail(final P1<E> e) { 789 return v.toEither().left().orValue(e); 790 } 791 792 /** 793 * Returns the failing value or the given value. 794 * 795 * @param e The value to return if this is success. 796 * @return The failing value or the given value. 797 */ 798 public E orFail(final E e) { 799 return orFail(p(e)); 800 } 801 802 /** 803 * The failing value or the application of the given function to the success value. 804 * 805 * @param f The function to execute on the success value. 806 * @return The failing value or the application of the given function to the success value. 807 */ 808 public E on(final F<T, E> f) { 809 return v.toEither().left().on(f); 810 } 811 812 /** 813 * Executes a side-effect on the failing value if there is one. 814 * 815 * @param f The side-effect to execute. 816 * @return The unit value. 817 */ 818 public Unit foreach(final F<E, Unit> f) { 819 return v.toEither().left().foreach(f); 820 } 821 822 /** 823 * Executes a side-effect on the failing value if there is one. 824 * 825 * @param f The side-effect to execute. 826 */ 827 public void foreach(final Effect<E> f) { 828 v.toEither().left().foreach(f); 829 } 830 831 /** 832 * Maps the given function across the failing side of this validation. 833 * 834 * @param f The function to map. 835 * @return A new validation with the function mapped. 836 */ 837 public <A> Validation<A, T> map(final F<E, A> f) { 838 return Validation.validation(v.toEither().left().map(f)); 839 } 840 841 /** 842 * Binds the given function across this validation's failing value if it has one. 843 * 844 * @param f The function to bind across this validation. 845 * @return A new validation value after binding. 846 */ 847 public <A> Validation<A, T> bind(final F<E, Validation<A, T>> f) { 848 return v.isFail() ? f.f(v.fail()) : Validation.<A, T>success(v.success()); 849 } 850 851 /** 852 * Performs a bind across the validation, but ignores the element value in the function. 853 * 854 * @param v The validation value to apply in the final join. 855 * @return A new validation value after the final join. 856 */ 857 public <A> Validation<A, T> sequence(final Validation<A, T> v) { 858 return bind(new F<E, Validation<A, T>>() { 859 public Validation<A, T> f(final E e) { 860 return v; 861 } 862 }); 863 } 864 865 /** 866 * Returns <code>None</code> if this is a success or if the given predicate <code>p</code> does not hold for the 867 * failing value, otherwise, returns a fail in <code>Some</code>. 868 * 869 * @param f The predicate function to test on this failing value. 870 * @return <code>None</code> if this is a success or if the given predicate <code>p</code> does not hold for the 871 * failing value, otherwise, returns a fail in <code>Some</code>. 872 */ 873 public <A> Option<Validation<E, A>> filter(final F<E, Boolean> f) { 874 return v.toEither().left().<A>filter(f).map(Validation.<E, A>validation()); 875 } 876 877 /** 878 * Function application on the failing value. 879 * 880 * @param v The validation of the function to apply on the failing value. 881 * @return The result of function application in validation. 882 */ 883 public <A> Validation<A, T> apply(final Validation<F<E, A>, T> v) { 884 return v.f().bind(new F<F<E, A>, Validation<A, T>>() { 885 public Validation<A, T> f(final F<E, A> f) { 886 return map(f); 887 } 888 }); 889 } 890 891 /** 892 * Returns <code>true</code> if this is a success or returns the result of the application of the given 893 * function to the failing value. 894 * 895 * @param f The predicate function to test on this failing value. 896 * @return <code>true</code> if this is a success or returns the result of the application of the given 897 * function to the failing value. 898 */ 899 public boolean forall(final F<E, Boolean> f) { 900 return v.toEither().left().forall(f); 901 } 902 903 /** 904 * Returns <code>false</code> if this is a success or returns the result of the application of the given 905 * function to the failing value. 906 * 907 * @param f The predicate function to test on this failing value. 908 * @return <code>false</code> if this is a success or returns the result of the application of the given 909 * function to the failing value. 910 */ 911 public boolean exists(final F<E, Boolean> f) { 912 return v.toEither().left().exists(f); 913 } 914 915 /** 916 * Returns a single element list if this is a failing value, otherwise an empty list. 917 * 918 * @return A single element list if this is a failing value, otherwise an empty list. 919 */ 920 public List<E> toList() { 921 return v.toEither().left().toList(); 922 } 923 924 /** 925 * Returns the failing value in <code>Some</code> if there is one, otherwise <code>None</code>. 926 * 927 * @return The failing value in <code>Some</code> if there is one, otherwise <code>None</code>. 928 */ 929 public Option<E> toOption() { 930 return v.toEither().left().toOption(); 931 } 932 933 /** 934 * Returns a single element array if this is a failing value, otherwise an empty list. 935 * 936 * @return A single element array if this is a failing value, otherwise an empty list. 937 */ 938 public Array<E> toArray() { 939 return v.toEither().left().toArray(); 940 } 941 942 /** 943 * Returns a single element stream if this is a failing value, otherwise an empty list. 944 * 945 * @return A single element stream if this is a failing value, otherwise an empty list. 946 */ 947 public Stream<E> toStream() { 948 return v.toEither().left().toStream(); 949 } 950 951 /** 952 * Returns an iterator for this projection. This method exists to permit the use in a <code>for</code>-each loop. 953 * 954 * @return A iterator for this projection. 955 */ 956 public Iterator<E> iterator() { 957 return v.toEither().left().iterator(); 958 } 959 } 960 961 /** 962 * Puts this validation's failing value in a non-empty list if there is one. 963 * 964 * @return A validation with its failing value in a non-empty list if there is one. 965 */ 966 @SuppressWarnings({"unchecked"}) 967 public Validation<NonEmptyList<E>, T> nel() { 968 return isSuccess() ? 969 Validation.<NonEmptyList<E>, T>success(success()) : 970 Validation.<NonEmptyList<E>, T>fail(NonEmptyList.nel(fail())); 971 } 972 973 /** 974 * Construct a validation using the given either value. 975 * 976 * @param e The either value to construct a validation with. 977 * @return A validation using the given either value. 978 */ 979 public static <E, T> Validation<E, T> validation(final Either<E, T> e) { 980 return new Validation<E, T>(e); 981 } 982 983 /** 984 * Returns a function that constructs a validation with an either. 985 * 986 * @return A function that constructs a validation with an either. 987 */ 988 public static <E, T> F<Either<E, T>, Validation<E, T>> validation() { 989 return new F<Either<E, T>, Validation<E, T>>() { 990 public Validation<E, T> f(final Either<E, T> e) { 991 return validation(e); 992 } 993 }; 994 } 995 996 /** 997 * Returns a function that constructs an either with a validation. 998 * 999 * @return A function that constructs an either with a validation. 1000 */ 1001 public static <E, T> F<Validation<E, T>, Either<E, T>> either() { 1002 return new F<Validation<E, T>, Either<E, T>>() { 1003 public Either<E, T> f(final Validation<E, T> v) { 1004 return v.toEither(); 1005 } 1006 }; 1007 } 1008 1009 /** 1010 * Returns a succeeding validation containing the given value. 1011 * 1012 * @param t The value to use in the succeeding validation. 1013 * @return A succeeding validation containing the given value. 1014 */ 1015 public static <E, T> Validation<E, T> success(final T t) { 1016 return validation(Either.<E, T>right(t)); 1017 } 1018 1019 /** 1020 * Returns a failing validation containing the given value. 1021 * 1022 * @param e The value to use in the failing validation. 1023 * @return A failing validation containing the given value. 1024 */ 1025 public static <E, T> Validation<E, T> fail(final E e) { 1026 return validation(Either.<E, T>left(e)); 1027 } 1028 1029 /** 1030 * Returns a failing validation containing a non-empty list that contains the given value. 1031 * 1032 * @param e The value to use in a non-empty list for the failing validation. 1033 * @return A failing validation containing a non-empty list that contains the given value. 1034 */ 1035 public static <E, T> Validation<NonEmptyList<E>, T> failNEL(final E e) { 1036 return fail(NonEmptyList.nel(e)); 1037 } 1038 1039 /** 1040 * Returns a validation based on a boolean condition. If the condition is <code>true</code>, the validation succeeds, 1041 * otherwise it fails. 1042 * 1043 * @param c The condition to base the returned validation on. 1044 * @param e The failing value to use if the condition is <code>false</code>. 1045 * @param t The succeeding value to use if the condition is <code>true</code>. 1046 * @return A validation based on a boolean condition. 1047 */ 1048 public static <E, T> Validation<E, T> condition(final boolean c, final E e, final T t) { 1049 return c ? Validation.<E, T>success(t) : Validation.<E, T>fail(e); 1050 } 1051 1052 /** 1053 * Parses the given string into a byte. 1054 * 1055 * @param s The string to parse. 1056 * @return A successfully parse byte or a failing exception. 1057 */ 1058 public static Validation<NumberFormatException, Byte> parseByte(final String s) { 1059 try { 1060 return success(Byte.parseByte(s)); 1061 } catch (NumberFormatException e) { 1062 return fail(e); 1063 } 1064 } 1065 1066 /** 1067 * Parses the given string into a double. 1068 * 1069 * @param s The string to parse. 1070 * @return A successfully parse double or a failing exception. 1071 */ 1072 public static Validation<NumberFormatException, Double> parseDouble(final String s) { 1073 try { 1074 return success(Double.parseDouble(s)); 1075 } catch (NumberFormatException e) { 1076 return fail(e); 1077 } 1078 } 1079 1080 /** 1081 * Parses the given string into a float. 1082 * 1083 * @param s The string to parse. 1084 * @return A successfully parse float or a failing exception. 1085 */ 1086 public static Validation<NumberFormatException, Float> parseFloat(final String s) { 1087 try { 1088 return success(Float.parseFloat(s)); 1089 } catch (NumberFormatException e) { 1090 return fail(e); 1091 } 1092 } 1093 1094 /** 1095 * Parses the given string into a integer. 1096 * 1097 * @param s The string to parse. 1098 * @return A successfully parse integer or a failing exception. 1099 */ 1100 public static Validation<NumberFormatException, Integer> parseInt(final String s) { 1101 try { 1102 return success(Integer.parseInt(s)); 1103 } catch (NumberFormatException e) { 1104 return fail(e); 1105 } 1106 } 1107 1108 /** 1109 * Parses the given string into a long. 1110 * 1111 * @param s The string to parse. 1112 * @return A successfully parse long or a failing exception. 1113 */ 1114 public static Validation<NumberFormatException, Long> parseLong(final String s) { 1115 try { 1116 return success(Long.parseLong(s)); 1117 } catch (NumberFormatException e) { 1118 return fail(e); 1119 } 1120 } 1121 1122 /** 1123 * Parses the given string into a short. 1124 * 1125 * @param s The string to parse. 1126 * @return A successfully parse short or a failing exception. 1127 */ 1128 public static Validation<NumberFormatException, Short> parseShort(final String s) { 1129 try { 1130 return success(Short.parseShort(s)); 1131 } catch (NumberFormatException e) { 1132 return fail(e); 1133 } 1134 } 1135 }