Programação Funcional em Swift: Nível Avançado

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course
Here is the translated HTML content in Portuguese (Português), with all HTML tags preserved and only the text content translated. Programming terms, code examples, and proper nouns remain in English. ```html

Programação Funcional em Swift: Nível Avançado



Swift foi originalmente projetado como uma linguagem multiparadigma, o que o torna uma plataforma ideal para aplicar técnicas avançadas de programação funcional. Neste artigo, exploraremos conceitos que vão além de closures básicas e map/filter/reduce — falaremos sobre functores, mônadas, composição de funções, currying e memoização. Essas ferramentas ajudarão você a escrever código mais previsível, testável e expressivo para aplicativos iOS e macOS.



Functores e Mônadas: Trabalhando com Contextos



Um functor é um tipo que implementa a função map, permitindo aplicar uma transformação a um valor dentro de um contexto. Em Swift, exemplos clássicos de functores são Optional e Array.



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

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


Uma mônada é um functor com uma operação adicional flatMap (ou >>= em Haskell). Ela permite "desembrulhar" contextos aninhados. Swift suporta mônadas implicitamente através do protocolo Monad, mas tipos-chave (Optional, Result, Async) implementam essa lógica.



// Mônada Optional: encadeamento de operações com possível 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)

// Mônada Result para tratamento de errosenum 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)


Aplicação avançada: criação de um tipo monádico personalizado para trabalhar com operações assíncronas.



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) }        }    }}


Composição de Funções: Construindo Pipelines



Composição de funções é a criação de uma nova função aplicando sequencialmente várias funções. Em Swift, isso pode ser implementado através de um operador ou closures.



// Operador de composiçãoprecedencegroup 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)) }}

// Exemplo: validação e formataçãolet 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!"


A composição é especialmente útil ao trabalhar com cadeias de transformações de dados, por exemplo, ao processar respostas de rede.



// Composição avançada com tratamento de errostypealias 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