Created
March 28, 2025 10:49
-
-
Save yoching/6c35d3faac43b1a76925d92c8550a8bf to your computer and use it in GitHub Desktop.
Basic of functor and monad in Swift
This file contains hidden or 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
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