-
Notifications
You must be signed in to change notification settings - Fork 136
Xor
Xor is a 'Right' (or primary type) biased disjunct union. Often called Either, but in a generics heavy Java world Xor is half the length of Either.
No 'projections' are provided, swap() and secondaryXXXX alternative methods can be used instead.
Xor inherits from the following cyclops types (and others) ApplicativeFunctor, Filterable, Foldable, Functor, MonadicValue1, To, Value,Visitable and Zippable.
## Examples
Xor is used to represent values that can be one of two states (for example a validation result, either everything is ok - or we have an error). It can be used to avoid a common design anti-pattern where an Object has two fields one of which is always null (or worse, both are defined as Optionals).
public class Member{
Xor<SeniorTeam,JuniorTeam> team;
}
Rather than
public class Member{
@Setter
SeniorTeam seniorTeam = null;
@Setter
JuniorTeam juniorTeam = null;
}
Xor's have two states
- Primary : Most methods operate naturally on the primary type, if it is present. If it is not, nothing happens.
- Secondary : Most methods do nothing to the secondary type if it is present.
To operate on the Secondary type first call swap() or use secondary analogs of the main operators.
Instantiating an Xor - Primary
Xor.primary("hello").map(v->v+" world")
//Xor.primary["hello world"]
Instantiating an Xor - Secondary
Xor.secondary("hello").map(v->v+" world")
//Xor.seconary["hello"]
Xor can operate (via map/flatMap) as a Functor / Monad and via combine as an ApplicativeFunctor
Values can be accumulated via
Xor.accumulateSecondary(ListX.of(Xor.secondary("failed1"),
Xor.secondary("failed2"),
Xor.primary("success")),
Semigroups.stringConcat)
//failed1failed2
Xor<String,String> fail1 = Xor.secondary("failed1");
fail1.swap().combine((a,b)->a+b)
.combine(Xor.secondary("failed2").swap())
.combine(Xor.<String,String>primary("success").swap())
//failed1failed2
Conversely accumulatePrimary is also available.
Combine values of any type asynchronously
Xor.primary(10)
.combine(Maybe.just(10),(a,b)->a+b);
//Primary[20]
orElse and coflatMap can be used to manage Xor's that aren't present and provide a default value.
int result = Xor.primary(10)
.orElse(-1); //10
int result = Xor.secondary("hello")
.orElse(-1); //-1
Xor.secondary()
.coflatMap(xor->xor.visit(s->10,p->p); //Xor.Primary[10]
We can use the visit method to execute a function depending on whether the Xor is primary or secondary
Xor.secondary(10)
.visit(s->"This is secondary",p->"This is primary"); //returns This is secondary
Xor.primary(10)
.visit(s->"This is secondary",p->"This is primary"); //returns This is primary
oops - my bad