public class TransactionExample { public static void main(String[] args) { Transactor, Unit, String> transactor = new Transactor<>() { @Override public IO> runTransactional(Transactional, String, Unit, A> transactional) { Unit connection = UNIT; return IO.io(() -> System.out.println("Starting Transaction")) .discardL(transactional.run(connection) .>>coerce() .flatMap(e -> e.match(s -> IO.io(() -> System.err.printf("Rolling back transaction due to %s%n", s)), __ -> IO.io(() -> System.out.println("Committing Transaction"))) .fmap(constantly(e)))); } }; Transactional, String, Unit, Integer> fetchOddNumber = new Transactional<>(pureIO(), readerT(context -> IO.io(() -> System.out.println("Fetching data")) .fmap(constantly(7)) .fmap(Either::right))); Transactional, String, Unit, Integer> fetchEvenNumber = new Transactional<>(pureIO(), readerT(context -> IO.io(() -> System.out.println("Fetching data")) .fmap(constantly(8)) .fmap(Either::right))); transactor.runTransactional(fetchOddNumber.flatMap(rollBackWhenOdd())) .>>coerce().unsafePerformIO(); transactor.runTransactional(fetchEvenNumber.flatMap(rollBackWhenOdd())) .>>coerce().unsafePerformIO(); } private static Fn1, String, Unit, ?>>> rollBackWhenOdd() { return integer -> { if (integer % 2 == 0) { return new Transactional<>(pureIO(), readerT(__ -> io(right(UNIT)))); // Commit } return new Transactional<>(pureIO(), readerT(__ -> io(left("Trigger rollback because odd integer")))); // Cancel; }; } }