Last active
July 21, 2025 15:12
-
-
Save jayrhynas/fd11e61ba9c0dd4ab046240fa9cfcd09 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct Memoize<each Arg: Hashable, R> { | |
typealias Generator = (repeat each Arg) -> R | |
private let generator: Generator | |
init(_ generator: @escaping Generator) { | |
self.generator = generator | |
} | |
private typealias Key = [AnyHashable] | |
private func makeKey(_ args: repeat each Arg) -> Key { | |
var key: [AnyHashable] = [] | |
for arg in repeat each args { | |
key.append(AnyHashable(arg)) | |
} | |
return key | |
} | |
private class Cache { | |
var storage: [Key: R] = [:] | |
} | |
private let cache = Cache() | |
private func computeAndCache(key: Key, _ args: repeat each Arg) -> R { | |
let result = generator(repeat each args) | |
cache.storage[key] = result | |
return result | |
} | |
func recompute(_ args: repeat each Arg) -> R { | |
computeAndCache(key: makeKey(repeat each args), repeat each args) | |
} | |
@discardableResult | |
func removeValue(for args: repeat each Arg) -> R? { | |
cache.storage.removeValue(forKey: makeKey(repeat each args)) | |
} | |
func callAsFunction(_ args: repeat each Arg) -> R { | |
let key = makeKey(repeat each args) | |
return cache.storage[key] ?? computeAndCache(key: key, repeat each args) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Tester { | |
func _calculate(a: Int, b: Int, c: Int) -> Int { | |
defer { print("calculated with \(a), \(b), \(c)")} | |
return a * a + b * b + c * c | |
} | |
private(set) lazy var calculate = Memoize(_calculate) | |
func main() { | |
print(calculate(2, 4, 6)) // calculated with 2, 4, 6 | |
// 56 | |
print(calculate(2, 4, 8)) // calculated with 2, 4, 8 | |
// 84 | |
print(calculate(2, 4, 6)) // 56 | |
print(calculate(2, 4, 8)) // 84 | |
calculate.removeValue(for: 2, 4, 6) | |
print(calculate(2, 4, 6)) // calculated with 2, 4, 6 | |
// 56 | |
print(calculate(2, 4, 8)) // 84 | |
} | |
} | |
Tester().main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment