Functional Programming in Swift: Advanced Level

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course
```html

Functional Programming in Swift: Advanced Level



Swift was originally designed as a multi-paradigm language, which makes it an ideal platform for applying advanced functional programming techniques. In this article, we will explore concepts that go beyond basic closures and map/filter/reduce — we will talk about functors, monads, function composition, currying, and memoization. These tools will help you write more predictable, testable, and expressive code for iOS and macOS applications.



Functors and Monads: Working with Contexts



A functor is a type that implements the map function, allowing you to apply a transformation to a value inside a context. In Swift, classic examples of functors are Optional and Array.



// Optional functorlet value: Int? = 42let result = value.map { $0 * 2 } // Optional(84)

// Array functorlet numbers = [1, 2, 3]let doubled = numbers.map { $0 * 2 } // [2, 4, 6]


A monad is a functor with an additional flatMap operation (or >>= in Haskell). It allows "unwrapping" nested contexts. Swift supports monads through the Monad protocol implicitly, but key types (Optional, Result, Async) implement this logic.



// Optional monad: chaining operations with possible nilfunc parseNumber(_ string: String) -> Int? { return Int(string) }func half(_ number: Int) -> Int? { return number % 2 == 0 ? number / 2 : nil }

let input = "42"let result = input.flatMap(parseNumber).flatMap(half) // Optional(21)

// Result monad for error handlingenum AppError: Error { case invalidInput }func safeDivide(_ a: Int, _ b: Int) -> Result<Int, AppError> { guard b != 0 else { return .failure(.invalidInput) } return .success(a / b)}

let divisionResult = safeDivide(10, 2).flatMap { safeDivide($0, 1) } // .success(5)


Advanced application: creating your own monadic type for working with asynchronous operations.



struct Async<T> {    let run: (@escaping (T) -> Void) -> Void        func map<U>(transform: @escaping (T) -> U) -> Async<U> {        return Async<U> { callback in            self.run { value in callback(transform(value)) }        }    }        func flatMap<U>(transform: @escaping (T) -> Async<U>) -> Async<U> {        return Async<U> { callback in            self.run { value in transform(value).run(callback) }        }    }}


Function Composition: Building a Pipeline



Function composition is creating a new function by sequentially applying several functions. In Swift, this can be implemented using an operator or closures.



// Composition operatorprecedencegroup CompositionPrecedence {    associativity: left    higherThan: FunctionArrowPrecedence}

infix operator >>> : CompositionPrecedence

func >>>(_ f: @escaping (A) -> B, _ g: @escaping (B) -> C) -> (A) -> C { return { x in g(f(x)) }}

// Example: validation and formattinglet trimWhitespace: (String) -> String = { $0.trimmingCharacters(in: .whitespaces) }let capitalize: (String) -> String = { $0.capitalized }let addExclamation: (String) -> String = { $0 + "!" }

let processString = trimWhitespace >>> capitalize >>> addExclamationprint(processString(" hello world ")) // "Hello World!"


Composition is especially useful when working with chains of data transformations, for example, when processing network responses.



// Advanced composition with error handlingtypealias ResultFunction = (T) -> Result<U, Error>

func compose(_ f: @escaping ResultFunction<T, U>, _ g: @escaping ResultFunction<U, V>) -> ResultFunction<T, V> { return { input ```

Blogs

Book Recommendations