Swift Functor、Applicative、Monad
Functor、Applicative、Monad:
- 解决同样的问题 - 将包装的值放入上下文(类)中
- 使用闭包[About]
- 返回上下文(类)的新实例
区别在于闭包的参数
伪代码:
class SomeClass<T> {
var wrappedValue: T //wrappedValue: - wrapped value
func foo<U>(function: ???) -> Functor<U> { //function: - function/closure
//logic
}
}
在哪里???
function: (T) -> U == Functor
function: SomeClass< (T) -> U > == Applicative
function: (T) -> SomeClass<U> == Monad
函子
Functor 将 function 应用于 wrapped value
伪代码:
class Functor<T> {
var value: T
func map<U>(function: (T) -> U) -> Functor<U> {
return Functor(value: function(value)) //<- apply a function to value
}
}
应用或应用函子
Applicative 将wrapped function 应用于wrapped value。
Functor 的差异是 wrapped function 而不是 function
伪代码:
class Applicative<T> {
var value: T
func apply<U>(function: Applicative< (T) -> U >) -> Applicative<U> {
return Applicative(value: unwrappedFunction(value))
}
}
单子
Monad 将function(返回wrapped value)应用于wrapped value
伪代码:
class Monad<T> {
var value: T
func flatMap<U>(function: (T) -> Monad<U>) -> Monad<U> { //function which returns a wrapped value
return function(value) //applies the function to a wrapped value
}
}
斯威夫特:
-
Optional, Collection, Result 是 Functor 和 Monad
-
String是函子
以可选为例
enum CustomOptional<T> {
case none
case some(T)
public init(_ some: T) {
self = .some(some)
}
//CustomOptional is Functor
func map<U>(_ transform: (T) -> U) -> CustomOptional<U> {
switch self {
case .some(let value):
let transformResult: U = transform(value)
let result: CustomOptional<U> = CustomOptional<U>(transformResult)
return result
case .none:
return .none
}
}
//CustomOptional is Applicative
func apply<U>(transformOptional: CustomOptional<(T) -> U>) -> CustomOptional<U> {
switch transformOptional {
case .some(let transform):
return self.map(transform)
case .none:
return .none
}
}
//CustomOptional is Monad
func flatMap<U>(_ transform: (T) -> CustomOptional<U>) -> CustomOptional<U> {
switch self {
case .some(let value):
let transformResult: CustomOptional<U> = transform(value)
let result: CustomOptional<U> = transformResult
return result
case .none:
return .none
}
}
}
[Swift Optional map vs flatMap]