具有关联类型 (Swift) 的 Functor 协议的实现
Implementation of Functor protocol with associated type (Swift)
我自己尝试在 Swift 中实现一个函子,发现我无法为 return 类型的通用映射函数指定不同的关联类型。不对的地方请大家多多指教
这是我的代码:
protocol Functor {
associatedtype T
func map<U>(_ transform: (T) -> U) -> Self // should return `Self` with associated type U
}
enum Result<A>: Functor {
typealias T = A
case success(A)
case failure(Error)
func map<U>(_ transform: (A) -> U) -> Result<A> { // autocompletion sets return type as `Result<A>` instead of Result<U>
switch self {
case let .success(value):
return .success(transform(value))
default:
return self
}
}
}
由于您打算通过应用 map
来更改 Functor
的关联类型,因此 return 类型在您的协议定义中不能是 Self
。这可以通过让 return 类型成为另一个关联类型来解决,该类型也是 Functor
(默认情况下可以是 Self
),可以自由选择类型通用结束。像这样:
protocol Functor {
associatedtype A
associatedtype B: Functor = Self
func map<C>(_ transform: (A) -> C) -> B where B.A == C
}
enum Result<Value>: Functor {
typealias A = Value
case success(Value)
case failure(Error)
func map<C>(_ transform: (A) -> C) -> Result<C> {
switch self {
case let .success(value): return .success(transform(value))
case let .failure(error): return .failure(error)
}
}
}
我自己尝试在 Swift 中实现一个函子,发现我无法为 return 类型的通用映射函数指定不同的关联类型。不对的地方请大家多多指教
这是我的代码:
protocol Functor {
associatedtype T
func map<U>(_ transform: (T) -> U) -> Self // should return `Self` with associated type U
}
enum Result<A>: Functor {
typealias T = A
case success(A)
case failure(Error)
func map<U>(_ transform: (A) -> U) -> Result<A> { // autocompletion sets return type as `Result<A>` instead of Result<U>
switch self {
case let .success(value):
return .success(transform(value))
default:
return self
}
}
}
由于您打算通过应用 map
来更改 Functor
的关联类型,因此 return 类型在您的协议定义中不能是 Self
。这可以通过让 return 类型成为另一个关联类型来解决,该类型也是 Functor
(默认情况下可以是 Self
),可以自由选择类型通用结束。像这样:
protocol Functor {
associatedtype A
associatedtype B: Functor = Self
func map<C>(_ transform: (A) -> C) -> B where B.A == C
}
enum Result<Value>: Functor {
typealias A = Value
case success(Value)
case failure(Error)
func map<C>(_ transform: (A) -> C) -> Result<C> {
switch self {
case let .success(value): return .success(transform(value))
case let .failure(error): return .failure(error)
}
}
}