Last active
February 9, 2025 03:32
-
-
Save ollieatkinson/9fb893edbde536f24dec79736285ebdf to your computer and use it in GitHub Desktop.
Implementation of `Tuple` type using Swift's new parameter packs
This file contains 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
public struct Tuple<each T> { | |
public private(set) var value: (repeat each T) | |
public init(_ value: repeat each T) { self.value = (repeat each value) } | |
} | |
extension Tuple { | |
public func map<each U>( | |
_ transform: (repeat each T) throws -> (repeat each U) | |
) rethrows -> (repeat each U) { | |
try (repeat each transform(repeat each value)) | |
} | |
public func flatMap<each U>( | |
_ transform: (repeat each T) throws -> Tuple<repeat each U> | |
) rethrows -> Tuple<repeat each U> { | |
try transform(repeat each value) | |
} | |
public func appending<U>( | |
_ item: U | |
) -> Tuple<repeat each T, U> { | |
Tuple<repeat each T, U>(repeat each value, item) | |
} | |
} | |
extension Tuple: Equatable where repeat each T: Equatable { | |
public static func == (lhs: Tuple<repeat each T>, rhs: Tuple<repeat each T>) -> Bool { | |
var result: [Bool] = [] | |
repeat result.append((each lhs.value) == (each rhs.value)) | |
return result.allSatisfy { $0 } | |
} | |
} | |
extension Tuple: Hashable where repeat each T: Hashable { | |
public func hash(into hasher: inout Hasher) { | |
repeat (each value).hash(into: &hasher) | |
} | |
} | |
extension Tuple: Comparable where repeat each T: Comparable { | |
public static func < (lhs: Tuple<repeat each T>, rhs: Tuple<repeat each T>) -> Bool { | |
var result: [Bool] = [] | |
repeat result.append((each lhs.value) < (each rhs.value)) | |
return result.allSatisfy { $0 } | |
} | |
} | |
extension Tuple: Sendable where repeat each T: Sendable {} | |
extension Tuple: Decodable where repeat each T: Decodable { | |
public init(from decoder: Decoder) throws { | |
var container = try decoder.unkeyedContainer() | |
try self.init(repeat (container.decode((each T).self))) | |
} | |
} | |
extension Tuple: Encodable where repeat each T: Encodable { | |
public func encode(to encoder: Encoder) throws { | |
var container = encoder.unkeyedContainer() | |
repeat try container.encode(each value) | |
} | |
} | |
extension Tuple: CustomStringConvertible where repeat each T: CustomStringConvertible { | |
public var description: String { | |
var values: [String] = [] | |
repeat values.append((each value).description) | |
return "\(Self.self)(\(values.joined(separator: ", ")))" | |
} | |
} | |
extension Tuple where repeat each T: OptionalProtocol { | |
public func get() throws -> Tuple<repeat (each T).Wrapped> { | |
Tuple<repeat (each T).Wrapped>(try repeat (each value).get()) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
OptionalProtocol
Map the tuple to a function
Unwrap each element in the tuple and map to a function