Skip to content

Instantly share code, notes, and snippets.

@yoching
Created March 28, 2025 10:49
Show Gist options
  • Save yoching/6c35d3faac43b1a76925d92c8550a8bf to your computer and use it in GitHub Desktop.
Save yoching/6c35d3faac43b1a76925d92c8550a8bf to your computer and use it in GitHub Desktop.
Basic of functor and monad in Swift
let array: Array<Int> = [1, 2, 3]
func double(input: Int) -> Int {
return input * 2
}
let mappedArray = array.map { value in
return double(input: value)
}
array.map(double) // point-free style
array.map({ double(input: $0) }) // not point-free style
// array has a map function
let optionalValue: Optional<Int> = nil // none or value
let mappedOptionalValue: Optional<Int> = optionalValue.map { value in
return value * 2
}
// some container that has a `map` is called Functor
//protocol Functor {
// associatedtype A
// associatedtype B
// func map(convert: ((A) -> B)) -> Array<B>
//}
//protocol Functor f {
// func myMap<AnotherType>(convert: (Element) -> AnotherType) -> f AnotherType
//}
extension Array {
func myMap<AnotherType>(convert: (Element) -> AnotherType) -> Array<AnotherType> {
var convertedElements: [AnotherType] = []
for element in self {
convertedElements.append(convert(element))
}
return convertedElements
}
}
extension Optional {
func myMap<AnotherType>(convert: (Wrapped) -> AnotherType) -> Optional<AnotherType> {
switch self {
case .none:
return .none
case .some(let wrappedValue):
return .some(convert(wrappedValue))
}
}
}
//
//
//Array<Int> // *
//Array<String> // *
//
//Array // Kind ** SomeType -> Array<SomeType>
//
//Result<Int, Error>
optionalValue.myMap(convert: { element in String(element * 2) })
[1,2,3].myMap(convert: { element in String(element * 2) })
protocol SomeCommonTrait {
func someCommonFunction()
}
extension Array: SomeCommonTrait {
func someCommonFunction() {
}
}
extension Optional: SomeCommonTrait {
func someCommonFunction() {
}
}
func something(x: SomeCommonTrait) {
x.someCommonFunction()
}
something(x: [1,2,3])
something(x: Optional.some(1))
let x1 : Array<Array<String>> = [1,2,3].map { element in
return [String(element), String(element)]
}
let x2: Array<String> = [1,2,3].flatMap { element in
return [String(element), String(element)]
}
let y1: Optional<Optional<String>> = optionalValue.map { value in
if value == 0 {
return Optional<String>.none
} else {
return Optional<String>.some(String(value))
}
}
let y2: Optional<String> = optionalValue.flatMap { value in
if value == 0 {
return Optional<String>.none
} else {
return Optional<String>.some(String(value))
}
}
//Result<Result<Result<Success, Error>, Error>, Error>
//Result<Success, Error>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment