// Path: core/src/main/java/eventsrc4j/SequenceQuery.java
// @data
// public abstract class SequenceQuery<S> {
//   public interface Cases<S, R> {
//     R Before(S s);
// 
//     R Earliest();
// 
//     R Latest();
//   }
// 
//   SequenceQuery() {
//   }
// 
// 
//   public abstract <R> R match(Cases<S, R> cases);
// 
//   @Override
//   public abstract int hashCode();
// 
//   @Override
//   public abstract boolean equals(Object obj);
// 
//   @Override
//   public abstract String toString();
// }
// 
// Path: core/src/main/java/eventsrc4j/Snapshot.java
// @data
// public abstract class Snapshot<S, V> {
// 
//   public interface Cases<S, V, R> {
// 
//     /**
//      * Events have been saved and there is a value stored.
//      *
//      * @param seq the point in the stream that this Snapshot is for.
//      * @param view the view on the stream upto to that point.
//      */
//     R Value(S seq, Instant time, V view);
// 
//     /**
//      * There is no snapshot... i.e. no events have been saved.
//      */
//     R NoSnapshot();
// 
//     /**
//      * Events have been saved and there is no value (i.e. the value has been deleted).
//      *
//      * @param seq Represents the point in the stream where the deletion occured.
//      */
//     R Deleted(S seq, Instant time);
//   }
// 
//   Snapshot() {
//   }
// 
//   public abstract <R> R match(Cases<S, V, R> cases);
// 
//   public final Option<S> seq() {
//     return getSeq(this);
//   }
// 
//   public final Option<Instant> time() {
//     return getTime(this);
//   }
// 
//   public final Option<V> view() {
//     return getView(this);
//   }
// 
//   @Override
//   public abstract int hashCode();
// 
//   @Override
//   public abstract boolean equals(Object obj);
// 
//   @Override
//   public abstract String toString();
// 
//   static final Equal<Instant> instantEqual = Equal.anyEqual();
//   static final Hash<Instant> instantHash = Hash.anyHash();
//   static final Show<Instant> instantShow = Show.anyShow();
//   static final Ord<Instant> instantOrd = Ord.comparableOrd();
// }
// 
// Path: core/src/main/java/eventsrc4j/SnapshotAction.java
// @FunctionalInterface
// public interface SnapshotAction<S, V, R> {
// 
//   /**
//    * Monadic SnapshotAction algebra.
//    *
//    * @param <R> action result type.
//    * @param <X> interpreted action result type (eg. wrapped in a container).
//    */
//   interface Algebra<S, V, R, X> extends Pure<R, X> {
// 
//     X Get(SequenceQuery<S> sequence, TypeEq<Snapshot<S, V>, R> resultType);
// 
//     X Put(Snapshot<S, V> snapshot, SnapshotStoreMode mode, TypeEq<Snapshot<S, V>, R> resultType);
// 
//     <Q> X Bind(SnapshotAction<S, V, Q> action, F<Q, SnapshotAction<S, V, R>> function);
//   }
// 
//   static <S, V> Factory<S, V> factory() {
//     return new Factory<S, V>() {};
//   }
// 
//   interface Factory<S, V> {
// 
//     default SnapshotAction<S, V, Snapshot<S, V>> GetSnapshot(SequenceQuery<S> sequence) {
//       return new SnapshotAction<S, V, Snapshot<S, V>>() {
//         @Override public <X> X eval(Algebra<S, V, Snapshot<S, V>, X> interpreter) {
//           return interpreter.Get(sequence, TypeEq.refl());
//         }
//       };
//     }
// 
//     default SnapshotAction<S, V, Snapshot<S, V>> PutSnapshot(Snapshot<S, V> snapshot, SnapshotStoreMode mode) {
//       return new SnapshotAction<S, V, Snapshot<S, V>>() {
//         @Override public <X> X eval(Algebra<S, V, Snapshot<S, V>, X> interpreter) {
//           return interpreter.Put(snapshot, mode, TypeEq.refl());
//         }
//       };
//     }
// 
//     default <R> SnapshotAction<S, V, R> PureSnapshotAction(R value) {
//       return new SnapshotAction<S, V, R>() {
//         @Override public <X> X eval(Algebra<S, V, R, X> interpreter) {
//           return interpreter.Pure(value);
//         }
//       };
//     }
//   }
// 
// 
//   default <Q> SnapshotAction<S, V, Q> bind(F<R, SnapshotAction<S, V, Q>> f) {
//     return new SnapshotAction<S, V, Q>() {
//       @Override public <X> X eval(Algebra<S, V, Q, X> interpreter) {
//         return interpreter.Bind(SnapshotAction.this, f);
//       }
//     };
//   }
// 
//   default <Q> SnapshotAction<S, V, Q> map(F<R, Q> f) {
//     return bind(r -> SnapshotAction.<S, V>factory().PureSnapshotAction(f.f(r)));
//   }
// 
// 
//   <X> X eval(SnapshotAction.Algebra<S, V, R, X> interpreter);
// 
// }
// 
// Path: core/src/main/java/eventsrc4j/SnapshotStoreMode.java
// @data
// public abstract class SnapshotStoreMode {
//   SnapshotStoreMode(){}
// 
//   public interface Cases<R> {
//     R Epoch();
//     R Cache();
//   }
// 
//   public abstract <R> R match(Cases<R> cases);
// 
//   @Override
//   public abstract int hashCode();
// 
//   @Override
//   public abstract boolean equals(Object obj);
// 
//   @Override
//   public abstract String toString();
// 
// }


import eventsrc4j.SequenceQuery;
import eventsrc4j.Snapshot;
import eventsrc4j.SnapshotAction;
import eventsrc4j.SnapshotStoreMode;
import fj.F;
import org.derive4j.hkt.TypeEq;
package eventsrc4j.io;


public interface SnapshotIOAlgebra<S, V, R> extends PureIO<R>, SnapshotAction.Algebra<S, V, R, IO<R>> {

  static <S, V, R> SnapshotIOAlgebra<S, V, R> of(SnapshotStream<S, V> eventStream) {

    return new SnapshotIOAlgebra<S, V, R>() {

// Path: core/src/main/java/eventsrc4j/SequenceQuery.java
// @data
// public abstract class SequenceQuery<S> {
//   public interface Cases<S, R> {
//     R Before(S s);
// 
//     R Earliest();
// 
//     R Latest();
//   }
// 
//   SequenceQuery() {
//   }
// 
// 
//   public abstract <R> R match(Cases<S, R> cases);
// 
//   @Override
//   public abstract int hashCode();
// 
//   @Override
//   public abstract boolean equals(Object obj);
// 
//   @Override
//   public abstract String toString();
// }
// 
// Path: core/src/main/java/eventsrc4j/Snapshot.java
// @data
// public abstract class Snapshot<S, V> {
// 
//   public interface Cases<S, V, R> {
// 
//     /**
//      * Events have been saved and there is a value stored.
//      *
//      * @param seq the point in the stream that this Snapshot is for.
//      * @param view the view on the stream upto to that point.
//      */
//     R Value(S seq, Instant time, V view);
// 
//     /**
//      * There is no snapshot... i.e. no events have been saved.
//      */
//     R NoSnapshot();
// 
//     /**
//      * Events have been saved and there is no value (i.e. the value has been deleted).
//      *
//      * @param seq Represents the point in the stream where the deletion occured.
//      */
//     R Deleted(S seq, Instant time);
//   }
// 
//   Snapshot() {
//   }
// 
//   public abstract <R> R match(Cases<S, V, R> cases);
// 
//   public final Option<S> seq() {
//     return getSeq(this);
//   }
// 
//   public final Option<Instant> time() {
//     return getTime(this);
//   }
// 
//   public final Option<V> view() {
//     return getView(this);
//   }
// 
//   @Override
//   public abstract int hashCode();
// 
//   @Override
//   public abstract boolean equals(Object obj);
// 
//   @Override
//   public abstract String toString();
// 
//   static final Equal<Instant> instantEqual = Equal.anyEqual();
//   static final Hash<Instant> instantHash = Hash.anyHash();
//   static final Show<Instant> instantShow = Show.anyShow();
//   static final Ord<Instant> instantOrd = Ord.comparableOrd();
// }
// 
// Path: core/src/main/java/eventsrc4j/SnapshotAction.java
// @FunctionalInterface
// public interface SnapshotAction<S, V, R> {
// 
//   /**
//    * Monadic SnapshotAction algebra.
//    *
//    * @param <R> action result type.
//    * @param <X> interpreted action result type (eg. wrapped in a container).
//    */
//   interface Algebra<S, V, R, X> extends Pure<R, X> {
// 
//     X Get(SequenceQuery<S> sequence, TypeEq<Snapshot<S, V>, R> resultType);
// 
//     X Put(Snapshot<S, V> snapshot, SnapshotStoreMode mode, TypeEq<Snapshot<S, V>, R> resultType);
// 
//     <Q> X Bind(SnapshotAction<S, V, Q> action, F<Q, SnapshotAction<S, V, R>> function);
//   }
// 
//   static <S, V> Factory<S, V> factory() {
//     return new Factory<S, V>() {};
//   }
// 
//   interface Factory<S, V> {
// 
//     default SnapshotAction<S, V, Snapshot<S, V>> GetSnapshot(SequenceQuery<S> sequence) {
//       return new SnapshotAction<S, V, Snapshot<S, V>>() {
//         @Override public <X> X eval(Algebra<S, V, Snapshot<S, V>, X> interpreter) {
//           return interpreter.Get(sequence, TypeEq.refl());
//         }
//       };
//     }
// 
//     default SnapshotAction<S, V, Snapshot<S, V>> PutSnapshot(Snapshot<S, V> snapshot, SnapshotStoreMode mode) {
//       return new SnapshotAction<S, V, Snapshot<S, V>>() {
//         @Override public <X> X eval(Algebra<S, V, Snapshot<S, V>, X> interpreter) {
//           return interpreter.Put(snapshot, mode, TypeEq.refl());
//         }
//       };
//     }
// 
//     default <R> SnapshotAction<S, V, R> PureSnapshotAction(R value) {
//       return new SnapshotAction<S, V, R>() {
//         @Override public <X> X eval(Algebra<S, V, R, X> interpreter) {
//           return interpreter.Pure(value);
//         }
//       };
//     }
//   }
// 
// 
//   default <Q> SnapshotAction<S, V, Q> bind(F<R, SnapshotAction<S, V, Q>> f) {
//     return new SnapshotAction<S, V, Q>() {
//       @Override public <X> X eval(Algebra<S, V, Q, X> interpreter) {
//         return interpreter.Bind(SnapshotAction.this, f);
//       }
//     };
//   }
// 
//   default <Q> SnapshotAction<S, V, Q> map(F<R, Q> f) {
//     return bind(r -> SnapshotAction.<S, V>factory().PureSnapshotAction(f.f(r)));
//   }
// 
// 
//   <X> X eval(SnapshotAction.Algebra<S, V, R, X> interpreter);
// 
// }
// 
// Path: core/src/main/java/eventsrc4j/SnapshotStoreMode.java
// @data
// public abstract class SnapshotStoreMode {
//   SnapshotStoreMode(){}
// 
//   public interface Cases<R> {
//     R Epoch();
//     R Cache();
//   }
// 
//   public abstract <R> R match(Cases<R> cases);
// 
//   @Override
//   public abstract int hashCode();
// 
//   @Override
//   public abstract boolean equals(Object obj);
// 
//   @Override
//   public abstract String toString();
// 
// }


// Path: core/src/main/java/eventsrc4j/io/SnapshotIOAlgebra.java
import eventsrc4j.SequenceQuery;
import eventsrc4j.Snapshot;
import eventsrc4j.SnapshotAction;
import eventsrc4j.SnapshotStoreMode;
import fj.F;
import org.derive4j.hkt.TypeEq;

package eventsrc4j.io;


public interface SnapshotIOAlgebra<S, V, R> extends PureIO<R>, SnapshotAction.Algebra<S, V, R, IO<R>> {

  static <S, V, R> SnapshotIOAlgebra<S, V, R> of(SnapshotStream<S, V> eventStream) {

    return new SnapshotIOAlgebra<S, V, R>() {

      @Override public IO<R> Get(SequenceQuery<S> sequence, TypeEq<Snapshot<S, V>, R> resultType) {