- Edit <EqA, A>
- Position
- Element
- MapOld (Func<A, A> f)
- MapNew (Func<A, A> f)
- Equals (object obj)
- == (Edit<EqA, A> a, Edit<EqA, A> b)
- != (Edit<EqA, A> a, Edit<EqA, A> b)
- GetHashCode ()
- Equals (Edit<EqA, A> other)
- Insert
- Insert (int position, A element)
- New (int position, A element)
- ToString ()
- MapOld (Func<A, A> f)
- MapNew (Func<A, A> f)
- Equals (Insert other)
- Equals (object obj)
- == (Insert a, Insert b)
- != (Insert a, Insert b)
- GetHashCode ()
- Delete
- Delete (int position, A element)
- New (int position, A element)
- ToString ()
- MapOld (Func<A, A> f)
- MapNew (Func<A, A> f)
- Equals (Delete other)
- Equals (object obj)
- == (Delete a, Delete b)
- != (Delete a, Delete b)
- GetHashCode ()
- Replace
- ReplaceElement
- Replace (int position, A element, A replaceElement)
- New (int position, A element, A replaceElement)
- ToString ()
- MapOld (Func<A, A> f)
- MapNew (Func<A, A> f)
- Equals (Replace other)
- Equals (object obj)
- == (Replace a, Replace b)
- != (Replace a, Replace b)
- GetHashCode ()
- Patch <EqA, A>
- Empty = new Patch<EqA, A>(Seq<Edit<EqA, A>>())
- Edits
- Equals (Patch<EqA, A> mb)
- Equals (object obj)
- == (Patch<EqA, A> pa, Patch<EqA, A> pb)
- != (Patch<EqA, A> pa, Patch<EqA, A> pb)
- + (Patch<EqA, A> pa, Patch<EqA, A> pb)
- - (Patch<EqA, A> pa)
- GetHashCode ()
- ToString ()
- Applicable (IEnumerable<A> document)
- Append (Patch<EqA, A> mb)
- Inverse ()
- SizeChange ()
- Apply (IEnumerable<A> va)
- Apply (Seq<A> va)
- Apply (Lst<A> va)
- Apply (SpanArray<A> va)
- Apply (Arr<A> va)
- Apply (A[] va)
- Apply (List<A> va)
- Patch
- unsafeFromSeq <EqA, A> (Seq<Edit<EqA, A>> edits)
- fromSeq <EqA, A> (Seq<Edit<EqA, A>> edits)
- append <EqA, A> (Patch<EqA, A> px, Patch<EqA, A> py)
- inverse <EqA, A> (Patch<EqA, A> patch)
- applicable <EqA, A> (Patch<EqA, A> pa, IEnumerable<A> va)
- composable <EqA, A> (Patch<EqA, A> pa, Patch<EqA, A> pb)
- sizeChange <EqA, A> (Patch<EqA, A> patch)
- apply <EqA, A> (Patch<EqA, A> patch, Lst<A> va)
- apply <EqA, A> (Patch<EqA, A> patch, Seq<A> va)
- apply <EqA, A> (Patch<EqA, A> patch, Arr<A> va)
- apply <EqA, A> (Patch<EqA, A> patch, A[] va)
- apply <EqA, A> (Patch<EqA, A> patch, SpanArray<A> va)
- apply <EqA, A> (Patch<EqA, A> patch, List<A> va)
- apply <EqA, A> (Patch<EqA, A> patch, IEnumerable<A> va)
- empty <EqA, A> ()
- ours <A> (A x, A y)
- theirs <A> (A x, A y)
- transform <MonoidEqA, A> (Patch<MonoidEqA, A> p, Patch<MonoidEqA, A> q)
- transformWith <EqA, A> (Func<A, A, A> conflict, Patch<EqA, A> p, Patch<EqA, A> q)
- diff <EqA, A> (IEnumerable<A> va, IEnumerable<A> vb)
Data type that represents an edit in a patch. Supports three sub-class 'cases':
Edit.Insert
Edit.Delete
Edit.Replace
These represent the total set of operations that can be represented in a Patch
type | EqA | |
type | A |
method Edit<EqA, A> MapOld (Func<A, A> f) Source #
Maps the outgoing value using the function provided. This has no effect on Insert
method Edit<EqA, A> MapNew (Func<A, A> f) Source #
Maps the new value using the function provided. This has no effect on Delete
method int GetHashCode () Source #
Hash code provider
Represents an Insert edit operation
method int GetHashCode () Source #
Represents an Delete edit operation
method int GetHashCode () Source #
Represents an Replace edit operation
field A ReplaceElement Source #
method int GetHashCode () Source #
struct Patch <EqA, A> Source #
A Patch
is a collection of edits performed to a document, in this case an 'IEnumerable'.
They are implemented as a list of 'Edit', and can be converted to and from raw lists of edits using
toList
and fromList
respectively.
Patches form a groupoid (a 'Monoid' with inverses, and a partial composition relation), where the
inverse element can be computed with 'inverse' and the groupoid operation is a composition of
patches. Applying append(p1, p2)
is the same as applying p1
then
p2
(see Patch.apply
). This composition operator may produce structurally different patches depending
on associativity, however the patches are guaranteed to be equivalent in the sense that the resultant
document will be the same when they are applied.
For convenience, we make our composition operator here total, to fit the Monoid
typeclass, but provide
some predicates (Patch.composable
and Patch.applicable
) to determine if the operation can be validly
used.
field Patch<EqA, A> Empty = new Patch<EqA, A>(Seq<Edit<EqA, A>>()) Source #
Empty patch
method int GetHashCode () Source #
Hash code provider
method bool Applicable (IEnumerable<A> document) Source #
Returns true if a patch can be safely applied to a document, that is,
applicable(p, d)
holds when d
is a valid source document for the patch p
.
method Patch<EqA, A> Append (Patch<EqA, A> mb) Source #
Monoid append: produces a patch is a merged version of this and the provided patch.
method int SizeChange () Source #
Returns the delta of the document's size when a patch is applied.
Essentially the number of Insert
minus the number of Delete
method IEnumerable<A> Apply (IEnumerable<A> va) Source #
Apply a patch to a document, returning the transformed document.
method IEnumerable<A> Apply (Seq<A> va) Source #
Apply a patch to a document, returning the transformed document.
method IEnumerable<A> Apply (Lst<A> va) Source #
Apply a patch to a document, returning the transformed document.
method IEnumerable<A> Apply (SpanArray<A> va) Source #
Apply a patch to a document, returning the transformed document.
method IEnumerable<A> Apply (Arr<A> va) Source #
Apply a patch to a document, returning the transformed document.
A Patch
is a collection of edits performed to a document, in this case an 'IEnumerable'.
They are implemented as a list of 'Edit', and can be converted to and from raw lists of edits using
toList
and fromList
respectively.
Patches form a groupoid (a 'Monoid' with inverses, and a partial composition relation), where the
inverse element can be computed with 'inverse' and the groupoid operation is a composition of
patches. Applying append(p1, p2)
is the same as applying p1
then
p2
(see Patch.apply
). This composition operator may produce structurally different patches depending
on associativity, however the patches are guaranteed to be equivalent in the sense that the resultant
document will be the same when they are applied.
For convenience, we make our composition operator here total, to fit the Monoid
typeclass, but provide
some predicates (Patch.composable
and Patch.applicable
) to determine if the operation can be validly
used.
method Patch<EqA, A> unsafeFromSeq <EqA, A> (Seq<Edit<EqA, A>> edits) Source #
Convert a list of edits to a patch, making sure to eliminate conflicting edits and sorting by index.
method Patch<EqA, A> fromSeq <EqA, A> (Seq<Edit<EqA, A>> edits) Source #
Convert a list of edits to a patch, making sure to eliminate conflicting edits and sorting by index.
method Patch<EqA, A> append <EqA, A> (Patch<EqA, A> px, Patch<EqA, A> py) Source #
Monoid append: produces a patch is a merged version of both provided patches.
method Patch<EqA, A> inverse <EqA, A> (Patch<EqA, A> patch) Source #
Compute the inverse of a patch
method bool applicable <EqA, A> (Patch<EqA, A> pa, IEnumerable<A> va) Source #
Returns true if a patch can be safely applied to a document, that is,
applicable(p, d)
holds when d
is a valid source document for the patch p
.
method bool composable <EqA, A> (Patch<EqA, A> pa, Patch<EqA, A> pb) Source #
Returns true if a patch can be validly composed with another.
That is, composable(p, q)
holds if q
can be validly applied after p
.
method int sizeChange <EqA, A> (Patch<EqA, A> patch) Source #
Returns the delta of the document's size when a patch is applied.
Essentially the number of Insert
minus the number of Delete
.
method Lst<A> apply <EqA, A> (Patch<EqA, A> patch, Lst<A> va) Source #
Apply a patch to a document, returning the transformed document.
method Seq<A> apply <EqA, A> (Patch<EqA, A> patch, Seq<A> va) Source #
Apply a patch to a document, returning the transformed document.
method Arr<A> apply <EqA, A> (Patch<EqA, A> patch, Arr<A> va) Source #
Apply a patch to a document, returning the transformed document.
method A[] apply <EqA, A> (Patch<EqA, A> patch, A[] va) Source #
Apply a patch to a document, returning the transformed document.
method SpanArray<A> apply <EqA, A> (Patch<EqA, A> patch, SpanArray<A> va) Source #
Apply a patch to a document, returning the transformed document.
method List<A> apply <EqA, A> (Patch<EqA, A> patch, List<A> va) Source #
Apply a patch to a document, returning the transformed document.
method IEnumerable<A> apply <EqA, A> (Patch<EqA, A> patch, IEnumerable<A> va) Source #
Apply a patch to a document, returning the transformed document.
method (Patch<MonoidEqA, A> a, Patch<MonoidEqA, A> b) transform <MonoidEqA, A> (Patch<MonoidEqA, A> p, Patch<MonoidEqA, A> q) Source #
A convenience version of transformWith
which resolves conflicts using append
.
method (Patch<EqA, A> a, Patch<EqA, A> b) transformWith <EqA, A> (Func<A, A, A> conflict, Patch<EqA, A> p, Patch<EqA, A> q) Source #
Given two diverging patches p
and q
, transform(m, p, q)
returns
a pair of updated patches (np, nq)
such that append(q, np)
and
append(p, nq)
are equivalent patches that incorporate the changes
of both p
and q
, up to merge conflicts, which are handled by
the provided function m
.
This is the standard transform
function of Operational Transformation
patch resolution techniques, and can be thought of as the pushout
of two diverging patches within the patch groupoid.
method Patch<EqA, A> diff <EqA, A> (IEnumerable<A> va, IEnumerable<A> vb) Source #
Compute the difference between two documents, using the Wagner-Fischer algorithm. O(mn) time and space.
apply(diff(d,e), d) == e
diff(d, d) == Patch.empty
apply(diff(d, e), d) == apply(inverse(diff(e, d)), d)
apply(append(diff(a, b), diff(b, c), a) == apply(diff(a, c), a)
applicable(diff(a, b) a)