protocol Mappable {
associatedtype Context<T> // this is the only impossible line
static func map<A, B>(_ fa: Context<A>, _ f: (A) -> B) -> Context<B>
}
extension Array: Mappable {
typealias Context<T> = Array<T>
static func map<A, B>(_ fa: Array<A>, _ f: (A) -> B) -> Array<B> {
fa.map(f)
}
}
extension Optional: Mappable {
typealias Context<T> = Optional<T>
static func map<A, B>(_ fa: Optional<A>, _ f: (A) -> B) -> Optional<B> {
fa.map(f)
}
}
extension Task: Mappable where Failure == Error {
typealias Context<T> = Task<T, Error>
static func map<A, B>(_ fa: Task<A, Error>, _ f: @escaping (A) -> B) -> Task<B, Error> {
Task {
let a = await fa.value
return f(a)
}
}
}
extension Result: Mappable where Failure == Error {
typealias Context<T> = Result<T, Error>
static func map<A, B>(_ fa: Result<A, Error>, _ f: (A) -> B) -> Result<B, Error> {
fa.map(f)
}
}