1
1
mirror of https://github.com/github/semantic.git synced 2024-11-25 11:04:00 +03:00

Merge pull request #106 from github/generalize-operation

Generalize Operation
This commit is contained in:
Josh Vera 2015-10-14 15:14:58 -04:00
commit 12130637f9
3 changed files with 40 additions and 39 deletions

View File

@ -22,6 +22,7 @@
D42F09791BCCC5DC00B95610 /* Prelude.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D42F09691BCCC41600B95610 /* Prelude.framework */; };
D42F097A1BCCC5DC00B95610 /* Stream.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D42F096A1BCCC41600B95610 /* Stream.framework */; };
D42F097C1BCE914A00B95610 /* Cofree.swift in Sources */ = {isa = PBXBuildFile; fileRef = D42F097B1BCE914A00B95610 /* Cofree.swift */; settings = {ASSET_TAGS = (); }; };
D42F097E1BCEAEDA00B95610 /* Operation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D42F097D1BCEAEDA00B95610 /* Operation.swift */; settings = {ASSET_TAGS = (); }; };
D432D4711BA9AC0B00F3FABC /* SESTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D432D4701BA9AC0B00F3FABC /* SESTests.swift */; };
D4413FEF1BB06D4C00E3C3C1 /* Dictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4413FEE1BB06D4C00E3C3C1 /* Dictionary.swift */; };
D4413FF11BB08FDC00E3C3C1 /* JSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4413FF01BB08FDC00E3C3C1 /* JSON.swift */; };
@ -64,6 +65,7 @@
D42F09691BCCC41600B95610 /* Prelude.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Prelude.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D42F096A1BCCC41600B95610 /* Stream.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Stream.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D42F097B1BCE914A00B95610 /* Cofree.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Cofree.swift; sourceTree = "<group>"; };
D42F097D1BCEAEDA00B95610 /* Operation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Operation.swift; sourceTree = "<group>"; };
D432D4701BA9AC0B00F3FABC /* SESTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SESTests.swift; sourceTree = "<group>"; };
D435B7521BB31BBC000902F6 /* BoundsCheckedArray.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoundsCheckedArray.swift; sourceTree = "<group>"; };
D4413FEE1BB06D4C00E3C3C1 /* Dictionary.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Dictionary.swift; sourceTree = "<group>"; };
@ -172,6 +174,7 @@
D42F097B1BCE914A00B95610 /* Cofree.swift */,
D49FCBC51BBF214300C5E9C3 /* Patch.swift */,
D49FCBC71BBF2C4300C5E9C3 /* Algorithm.swift */,
D42F097D1BCEAEDA00B95610 /* Operation.swift */,
D4DF96EC1BC46B630040F41F /* SES.swift */,
D435B7521BB31BBC000902F6 /* BoundsCheckedArray.swift */,
D4AAE5001B5AE22E004E581F /* Supporting Files */,
@ -350,6 +353,7 @@
D4AAE5471B5AE2D0004E581F /* Optional.swift in Sources */,
D4413FEF1BB06D4C00E3C3C1 /* Dictionary.swift in Sources */,
D4D7F3171BBB22E500AAB0C0 /* Hash.swift in Sources */,
D42F097E1BCEAEDA00B95610 /* Operation.swift in Sources */,
D45A36C91BBC667D00BE3DDE /* Category.swift in Sources */,
D4DF96ED1BC46B630040F41F /* SES.swift in Sources */,
D4AAE5401B5AE2D0004E581F /* RangeReplaceableCollectionType.swift in Sources */,

View File

@ -1,38 +1,3 @@
/// An operation of diffing over terms or collections of terms.
public enum Operation<Recur, A> {
/// The type of `Term`s over which `Operation`s operate.
public typealias Term = Fix<A>
/// The type of `Diff`s which `Operation`s produce.
public typealias Diff = Free<A, Patch<A>>
/// Indicates that diffing should compare the enclosed `Term`s.
///
/// When run, the enclosed function will be applied to the resulting `Diff`.
case Recursive(Term, Term, Diff -> Recur)
/// Represents a diff to be performed on a collection of terms identified by keys.
case ByKey([String:Term], [String:Term], [String:Diff] -> Recur)
/// Represents a diff to be performed over an array of terms by index.
case ByIndex([Term], [Term], [Diff] -> Recur)
// MARK: Functor
public func map<Other>(transform: Recur -> Other) -> Operation<Other, A> {
switch self {
case let .Recursive(a, b, f):
return .Recursive(a, b, f >>> transform)
case let .ByKey(a, b, f):
return .ByKey(a, b, f >>> transform)
case let .ByIndex(a, b, f):
return .ByIndex(a, b, f >>> transform)
}
}
}
/// The free monad over `Operation`, implementing the language of diffing.
///
/// As with `Free`, this is free in the sense of unconstrained, i.e. the monad induced by `Operation` without extra assumptions.
@ -40,10 +5,10 @@ public enum Operation<Recur, A> {
/// Where `Operation` models a single diffing strategy, `Algorithm` models the recursive selection of diffing strategies at each node. Thus, a value in `Algorithm` models an algorithm for constructing a value in the type `B` from the resulting diffs. By this means, diffing can be adapted not just to the specific grammar, but to specific trees produced by that grammar, and even the values of type `A` encapsulated at each node.
public enum Algorithm<A, B> {
/// The type of `Term`s over which `Algorithm`s operate.
public typealias Term = Operation<Algorithm, A>.Term
public typealias Term = Fix<A>
/// The type of `Diff`s which `Algorithm`s produce.
public typealias Diff = Operation<Algorithm, A>.Diff
public typealias Diff = Free<A, Patch<A>>
/// The injection of a value of type `B` into an `Operation`.
///
@ -51,9 +16,9 @@ public enum Algorithm<A, B> {
case Pure(B)
/// A recursive instantiation of `Operation`, unrolling another iteration of the recursive type.
case Roll(Operation<Algorithm, A>)
case Roll(Operation<Algorithm, Term, Diff>)
public func analysis<C>(@noescape ifPure ifPure: B -> C, @noescape ifRoll: Operation<Algorithm, A> -> C) -> C {
public func analysis<C>(@noescape ifPure ifPure: B -> C, @noescape ifRoll: Operation<Algorithm, Term, Diff> -> C) -> C {
switch self {
case let .Pure(b):
return ifPure(b)

View File

@ -0,0 +1,32 @@
/// An operation of diffing over terms or collections of terms.
public enum Operation<Recur, Term, Diff> {
/// Indicates that diffing should compare the enclosed `Term`s.
///
/// When run, the enclosed function will be applied to the resulting `Diff`.
case Recursive(Term, Term, Diff -> Recur)
/// Represents a diff to be performed on a collection of terms identified by keys.
case ByKey([String:Term], [String:Term], [String:Diff] -> Recur)
/// Represents a diff to be performed over an array of terms by index.
case ByIndex([Term], [Term], [Diff] -> Recur)
}
// MARK: - Functor
extension Operation {
public func map<Other>(transform: Recur -> Other) -> Operation<Other, Term, Diff> {
switch self {
case let .Recursive(a, b, f):
return .Recursive(a, b, f >>> transform)
case let .ByKey(a, b, f):
return .ByKey(a, b, f >>> transform)
case let .ByIndex(a, b, f):
return .ByIndex(a, b, f >>> transform)
}
}
}
import Prelude