diff --git a/prototype/Doubt.xcodeproj/project.pbxproj b/prototype/Doubt.xcodeproj/project.pbxproj index 35c301881..f713e1ec6 100644 --- a/prototype/Doubt.xcodeproj/project.pbxproj +++ b/prototype/Doubt.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ D432D4711BA9AC0B00F3FABC /* DiffTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D432D4701BA9AC0B00F3FABC /* DiffTests.swift */; }; D432D4731BA9C55300F3FABC /* Stream.swift in Sources */ = {isa = PBXBuildFile; fileRef = D432D4721BA9C55300F3FABC /* Stream.swift */; }; + D432D4751BA9D6A400F3FABC /* Memo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D432D4741BA9D6A400F3FABC /* Memo.swift */; }; D4AAE50E1B5AE22E004E581F /* Doubt.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4AAE4FD1B5AE22E004E581F /* Doubt.framework */; }; D4AAE5131B5AE22E004E581F /* DoubtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4AAE5121B5AE22E004E581F /* DoubtTests.swift */; }; D4AAE5401B5AE2D0004E581F /* Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4AAE5351B5AE2D0004E581F /* Array.swift */; }; @@ -37,6 +38,7 @@ /* Begin PBXFileReference section */ D432D4701BA9AC0B00F3FABC /* DiffTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DiffTests.swift; sourceTree = ""; }; D432D4721BA9C55300F3FABC /* Stream.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Stream.swift; sourceTree = ""; }; + D432D4741BA9D6A400F3FABC /* Memo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Memo.swift; sourceTree = ""; }; D4AAE4FD1B5AE22E004E581F /* Doubt.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Doubt.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D4AAE5011B5AE22E004E581F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; D4AAE50D1B5AE22E004E581F /* DoubtTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DoubtTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -107,6 +109,7 @@ D4AAE53F1B5AE2D0004E581F /* Syntax.swift */, D4AAE54B1B5AE42D004E581F /* Equatable.swift */, D432D4721BA9C55300F3FABC /* Stream.swift */, + D432D4741BA9D6A400F3FABC /* Memo.swift */, D4AAE5001B5AE22E004E581F /* Supporting Files */, ); path = Doubt; @@ -247,6 +250,7 @@ D432D4731BA9C55300F3FABC /* Stream.swift in Sources */, D4AAE5421B5AE2D0004E581F /* Doc.swift in Sources */, D4AAE5461B5AE2D0004E581F /* Parse.swift in Sources */, + D432D4751BA9D6A400F3FABC /* Memo.swift in Sources */, D4AAE5491B5AE2D0004E581F /* StringLiteralConvertible.swift in Sources */, D4AAE5451B5AE2D0004E581F /* Operators.swift in Sources */, ); diff --git a/prototype/Doubt/Memo.swift b/prototype/Doubt/Memo.swift new file mode 100644 index 000000000..c3df13e0e --- /dev/null +++ b/prototype/Doubt/Memo.swift @@ -0,0 +1,31 @@ +public struct Memo { + public var value: A { + return _value.value.value() + } + + private var _value: MutableBox> +} + +private final class MutableBox { + init(_ value: A) { + self.value = value + } + + var value: A +} + +private enum Thunk { + case Evaluated(A) + case Unevaluated(() -> A) + + mutating func value() -> A { + switch self { + case let .Evaluated(a): + return a + case let .Unevaluated(f): + let a = f() + self = .Evaluated(a) + return a + } + } +}