1
1
mirror of https://github.com/github/semantic.git synced 2024-12-22 14:21:31 +03:00
semantic/prototype/Doubt/Memo.swift

62 lines
1.1 KiB
Swift
Raw Normal View History

2015-09-25 18:57:28 +03:00
public struct Memo<A>: CustomDebugStringConvertible, CustomStringConvertible {
2015-09-16 20:42:31 +03:00
public init(unevaluted: () -> A) {
self.init(.Unevaluated(unevaluted))
}
public init(evaluated: A) {
2015-09-16 20:42:31 +03:00
self.init(.Evaluated(evaluated))
}
private init(_ thunk: Thunk<A>) {
_value = MutableBox(thunk)
}
2015-09-16 19:59:57 +03:00
public var value: A {
return _value.value.value()
}
private var _value: MutableBox<Thunk<A>>
2015-09-17 21:10:51 +03:00
public func map<B>(transform: A -> B) -> Memo<B> {
return Memo<B> { transform(self.value) }
}
2015-09-17 21:36:34 +03:00
public func flatMap<B>(transform: A -> Memo<B>) -> Memo<B> {
return Memo<B> { transform(self.value).value }
}
2015-09-25 18:57:28 +03:00
public var description: String {
return String(value)
}
public var debugDescription: String {
return String(reflecting: value)
}
2015-09-16 19:59:57 +03:00
}
private final class MutableBox<A> {
init(_ value: A) {
self.value = value
}
var value: A
}
private enum Thunk<A> {
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
}
}
}