Programmation fonctionnelle en Swift : niveau avancé

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Programmation fonctionnelle en Swift : niveau avancé

\n\n

La programmation fonctionnelle (PF) est un paradigme qui considère les calculs comme l'évaluation de fonctions mathématiques et évite les changements d'état et les données mutables. En Swift, qui est un langage multiparadigme, les capacités fonctionnelles ne sont pas simplement prises en charge, mais profondément intégrées dans le langage et la bibliothèque standard. Si vous maîtrisez déjà les concepts de base comme map, filter et reduce, il est temps d'approfondir les techniques avancées qui vous aideront à écrire un code plus sûr, plus prévisible et plus testable pour les applications iOS et macOS. Dans cet article, nous explorerons les foncteurs, les monades, l'évaluation paresseuse et la composition de fonctions à l'aide d'exemples pratiques.

\n\n

1. Foncteurs : conteneurs avec capacité de transformation

\n\n

Un foncteur est un type de données qui implémente la fonction fmap (en Swift — map). L'essence d'un foncteur est qu'il représente un conteneur dont le contenu peut être transformé à l'aide d'une fonction passée, sans sortir du conteneur. L'exemple classique est Optional.

\n\n

Voyons comment fonctionne un foncteur avec l'exemple de Optional :

\n\n
let maybeNumber: Int? = 5\nlet result = maybeNumber.map { $0 * 2 }\nprint(result) // Optional(10)\n\nlet nilValue: Int? = nil\nlet nilResult = nilValue.map { $0 * 2 }\nprint(nilResult) // nil
\n\n

Ici, Optional est un foncteur. S'il y a une valeur à l'intérieur, map applique la fermeture et retourne un nouveau Optional. S'il n'y a pas de valeur, l'opération n'est pas exécutée et nous obtenons nil. Cela évite les constructions lourdes if let.

\n\n

Un autre foncteur important en Swift est Array. map sur un tableau applique la fonction à chaque élément et retourne un nouveau tableau :

\n\n
let numbers = [1, 2, 3, 4]\nlet doubled = numbers.map { $0 * 2 }\nprint(doubled) // [2, 4, 6, 8]
\n\n

Créer son propre foncteur. Vous pouvez implémenter un foncteur pour tout type personnalisé en définissant la méthode map. Par exemple, une simple enveloppe de journalisation :

\n\n
struct Logged<T> {\n    let value: T\n    let log: [String]\n    \n    func map<U>(_ transform: (T) -> U) -> Logged<U> {\n        let newValue = transform(value)\n        return Logged<U>(value: newValue, log: log + ["Transformé \\(value) en \\(newValue)"])\n    }\n}\n\nlet logged = Logged(value: 10, log: ["Valeur initiale"])\nlet transformed = logged.map { $0 + 5 }\nprint(transformed.log) // ["Valeur initiale", "Transformé 10 en 15"]
\n\n

2. Monades : chaînes de calculs avec contexte

\n\n

Une monade est un foncteur qui implémente en plus la méthode flatMap (ou bind). Si map permet d'appliquer une fonction qui retourne une valeur ordinaire, flatMap permet d'appliquer une fonction qui retourne elle-même une valeur dans le même contexte (par exemple, un autre Optional). C'est un outil clé pour construire des chaînes d'opérations tout en conservant le contexte.

\n\n

L'exemple le plus parlant est le travail avec les valeurs optionnelles. Supposons que nous ayons une fonction qui extrait un nombre d'une chaîne, et une fonction qui divise un nombre par un autre, mais toutes deux peuvent retourner nil :

\n\n
func parseNumber(_ string: String) -> Int? {\n    return Int(string)\n}\n\nfunc divideSafely(_ a: Int, by b: Int) -> Int? {\n    guard b != 0 else { return nil }\n    return a / b\n}\n\n// Sans flatMap, on doit utiliser des if let imbriqués\nif let num1 = parseNumber("10") {\n    if let result = divideSafely(num1, by: 2) {\n        print(result) // 5\n    }\n}\n\n// Avec flatMap, tout devient plus élégant\nlet result = parseNumber("10").flatMap { divideSafely($0, by: 2) }\nprint(result) // Optional(5)\n\nlet failed = parseNumber("abc").flatM                

Blogs

Book Recommendations