🚀 CE - Fondements thĂ©oriques

CE = Computation Expression

CE : le couteau suisse ✹

Les computation expressions servent à différentes choses :

  • C♯ yield return → F♯ seq {}

  • C♯ async/await → F♯ async {}

  • C♯ expressions LINQ from... select → F♯ query {}

  • ...

Fondements théoriques sous-jacents :

  • MonoĂŻde

  • Monade

  • Applicative

MonoĂŻde

≃ Type T dĂ©finissant un ensemble comportant :

  1. Opération (+) : T -> T -> T

    • Pour combiner des ensembles et garder le mĂȘme "type"

    • Associative : a + (b + c) ≡ (a + b) + c

  2. ÉlĂ©ment neutre (aka identity) ≃ ensemble vide

    • Combinable Ă  tout ensemble sans effet

    • a + e ≡ e + a ≡ a

CE monoĂŻdale

Le builder d'une CE monoĂŻdale (telle que seq) dispose a minima de :

  • Yield pour construire l'ensemble Ă©lĂ©ment par Ă©lĂ©ment

  • Combine ≡ (+) (Seq.append)

  • Zero ≡ Ă©lĂ©ment neutre (Seq.empty)

S'y ajoute généralement (entre autres) :

  • For pour supporter for x in xs do ...

  • YieldFrom pour supporter yield!

Monade

≃ Type gĂ©nĂ©rique M<'T> comportant :

  1. Fonction return de construction

    • Signature : (value: 'T) -> M<'T>

    • ≃ Wrap une valeur

  2. Fonction bind de "liaison" (aka opérateur >>=)

    • Signature : (f: 'T -> M<'U>) -> M<'T> -> M<'U>

    • Utilise la valeur wrappĂ©e, la "map" avec la fonction f vers une valeur d'un autre type et "re-wrap" le rĂ©sultat

Lois

return ≡ Ă©lĂ©ment neutre pour bind

  • À gauche : return x |> bind f ≡ f x

  • À droite : m |> bind return ≡ m

bind est associatif

  • m |> bind f |> bind g ≡ m |> bind (fun x -> f x |> bind g)

Langages

Haskell

  • Monades beaucoup utilisĂ©es. Les + communes : IO, Maybe, State, Reader.

  • Monad est une classe de type pour crĂ©er facilement ses propres monades.

F♯

  • Certaines CE permettent des opĂ©rations monadiques.

  • Plus rarement utilisĂ©es directement (sauf par des Haskellers)

C♯

  • Monade implicite dans LINQ

  • Librairie LanguageExt de programmation fonctionnelle

CE monadique

Le builder d'une CE monadique dispose des méthodes Return et Bind.

Les types Option et Result sont monadiques. → On peut leur crĂ©er leur propre CE :

CE monadique et générique

FSharpPlus propose une CE monad → Marche pour tous les types monadiques : Option, Result, ... et mĂȘme Lazy !

Exemple avec le type Option

⚠ Limite : on ne peut pas mĂ©langer plusieurs types monadiques !

CE monadiques spécifiques

Librairie FsToolkit.ErrorHandling propose : ‱ CE option {} spĂ©cifique au type Option<'T> (exemple ci-dessous) ‱ CE result {} spĂ©cifique au type Result<'Ok, 'Err>

☝ RecommandĂ© car + explicite que CE monad

Applicative

A.k.a Applicative Functor

≃ Type gĂ©nĂ©rique M<'T>

3 "styles" :

Style A : Applicatives avec apply/<*> et pure/return ‱ ❌ Pas facile Ă  comprendre ‱ 💡 PrĂ©sentĂ© par JĂ©rĂ©mie Chassaing dans le talk ❝Applicatives in real life❞ ‱ ☝ DĂ©conseillĂ© par Don Syme dans cette note de nov. 2020

Style B : Applicatives avec mapN ‱ map2, map3... map5 combine 2 Ă  5 valeurs wrappĂ©es

Style C : Applicatives avec let! ... and! ... dans une CE ‱ MĂȘme principe : combiner plusieurs valeurs wrappĂ©es ‱ Disponible Ă  partir de F♯ 5 (annonce de nov. 2020)

☝ Conseil : Styles B et C sont autant recommandĂ©s l'un que l'autre.

CE applicative

Librairie FsToolkit.ErrorHandling propose : ‱ Type Validation<'Ok, 'Err> ≡ Result<'Ok, 'Err list> ‱ CE validation {} supportant syntaxe let!...and!...

Permet d'accumuler les erreurs → Usages : ‱ Parsing d'inputs externes ‱ Smart constructor (Exemple de code slide suivante...)

Applicative vs Monade

Soit N opérations tryXxx renvoyant un Option ou Result

Style monadique :

  • Avec bind ou CE let! ... let! ...

  • ChaĂźne les opĂ©rations, exĂ©cutĂ©e 1 Ă  1, la N dĂ©pendant de la N-1

  • S'arrĂȘte Ă  1Ăšre opĂ©ration KO → juste 1Ăšre erreur dans Result ①

Style applicatif :

  • Avec mapN ou CE let! ... and! ...

  • Combine 2..N opĂ©rations indĂ©pendantes → parallĂ©lisables 👍

  • Permet de combiner les cas Error contenant une List ②

Autres CE

On a vu 2 librairies qui Ă©tendent F♯ et proposent leurs CE :

  • FSharpPlus → monad

  • FsToolkit.ErrorHandling → option, result, validation

Beaucoup de librairies ont leur propre DSL (Domain Specific Language.) Certaines s'appuient alors sur des CE :

  • Expecto

  • Farmer

  • Saturn

Expecto

❝ Librairie de testing : assertions + runner ❞ 🔗 https://github.com/haf/expecto

Farmer

❝ Infrastructure-as-code pour Azure ❞

🔗 github.com/compositionalit/farmer

Saturn

❝ Framework Web au-dessus de ASP.NET Core, pattern MVC ❞

🔗 saturnframework.org

Aller + loin

đŸ“č Extending F# through Computation Expressions - 📜 Slides

🔗 Computation Expressions Workshop

Mis Ă  jour

Ce contenu vous a-t-il Ă©tĂ© utile ?