Skip to content
johnmcclean-aol edited this page Nov 23, 2016 · 6 revisions

eXclusive Or (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.

Class Hierarchy

Xor inherits from the following cyclops types (and others) ApplicativeFunctor, Filterable, Foldable, Functor, MonadicValue1, To, Value,Visitable and Zippable.

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

  1. Primary : Most methods operate naturally on the primary type, if it is present. If it is not, nothing happens.
  2. 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

Clone this wiki locally