diff options
Diffstat (limited to 'fr-fr')
| -rw-r--r-- | fr-fr/fsharp-fr.html.markdown | 630 | 
1 files changed, 630 insertions, 0 deletions
| diff --git a/fr-fr/fsharp-fr.html.markdown b/fr-fr/fsharp-fr.html.markdown new file mode 100644 index 00000000..7336c6aa --- /dev/null +++ b/fr-fr/fsharp-fr.html.markdown @@ -0,0 +1,630 @@ +--- +language: F# +contributors: +    - ["Scott Wlaschin", "http://fsharpforfunandprofit.com/"] +translators: +    - ["Alois de Gouvello", "https://github.com/aloisdg"] +filename: learnfsharp-fr.fs +--- + +F# est un langage de programmation fonctionnel et orienté objet. Il est gratuit et son code source est ouvert. Il tourne sur Linux, Mac, Windows et plus. + +Il possède un puissant système de type qui piège de nombreuses erreurs à la compilation, mais il utilise l'inférence de type ce qui lui permet d'être lu comme un langage dynamique. + +La syntaxe de F# est différente des langages héritant de C. + +* Les accolades ne sont pas utilisées pour délimiter les blocs de code. À la place, l'indentation est utilisée (à la manière de Python). +* Les espaces sont utilisés pour séparer les paramètres à la place des virgules. + +Si vous voulez essayer le code ci-dessous, vous pouvez vous rendre sur [tryfsharp.org](http://www.tryfsharp.org/Create) et le coller dans le [REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop). + +```fsharp + +// Les commentaires d'une seule ligne commencent par un double slash +(* Les commentaires multilignes utilise les paires (* . . . *) + +-fin du commentaire multilignes- *) + +// ================================================ +// Syntaxe de base +// ================================================ + +// ------ "Variables" (mais pas vraiment) ------ +// Le mot clé "let" définit une valeur (immutable) +let myInt = 5 +let myFloat = 3.14 +let myString = "hello"           // Notons qu'aucun type n'est nécessaire + +// ------ Listes ------ +let twoToFive = [2;3;4;5]        // Les crochets créent une liste avec +                                 // des point-virgules pour délimiteurs. +let oneToFive = 1 :: twoToFive   // :: crée une liste avec un nouvel élément +// Le résultat est [1;2;3;4;5] +let zeroToFive = [0;1] @ twoToFive   // @ concatène deux listes + +// IMPORTANT: les virgules ne sont jamais utilisées pour délimiter, +// seulement les point-virgules ! + +// ------ Fonctions ------ +// Le mot clé "let" définit aussi le nom d'une fonction. +let square x = x * x          // Notons qu'aucune parenthèse n'est utilisée. +square 3                      // Maitenant, exécutons la fonction. +                              // Encore une fois, aucune parenthèse. + +let add x y = x + y           // N'utilisez pas add (x,y) ! Cela signifie +                              // quelque chose de complètement différent. +add 2 3                       // À présent, exécutons la fonction. + +// Pour définir une fonction sur plusieurs lignes, utilisons l'indentation. +// Les point-virgules ne sont pas nécessaires. +let evens list = +   let isEven x = x%2 = 0     // Définit "isEven" comme une fonction imbriquée +   List.filter isEven list    // List.filter est une fonction de la librairie +                              // à deux paramètres: un fonction retournant un +                              // booléen et une liste sur laquelle travailler + +evens oneToFive               // À présent, exécutons la fonction. + +// Vous pouvez utilisez les parenthèses pour clarifier. +// Dans cet exemple, "map" est exécutée en première, avec deux arguments, +// ensuite "sum" est exécutée sur le résultat. +// Sans les parenthèses, "List.map" serait passé en argument à List.sum. +let sumOfSquaresTo100 = +   List.sum ( List.map square [1..100] ) + +// Vous pouvez rediriger la sortie d'une fonction vers une autre avec "|>" +// Rediriger des données est très commun en F#, comme avec les pipes UNIX. + +// Voici la même fonction sumOfSquares écrite en utilisant des pipes +let sumOfSquaresTo100piped = +   [1..100] |> List.map square |> List.sum  // "square" est déclaré avant + +// Vous pouvez définir des lambdas (fonctions anonymes) grâce au mot clé "fun" +let sumOfSquaresTo100withFun = +   [1..100] |> List.map (fun x -> x*x) |> List.sum + +// En F#, il n'y a pas de mot clé "return". Une fonction retourne toujours +// la valeur de la dernière expression utilisée. + +// ------ Pattern Matching ------ +// Match..with.. est une surcharge de la condition case/switch. +let simplePatternMatch = +   let x = "a" +   match x with +    | "a" -> printfn "x is a" +    | "b" -> printfn "x is b" +    | _ -> printfn "x is something else"   // underscore correspond à tout le reste + +// F# n'autorise pas la valeur null par défaut -- vous devez utiliser le type Option +// et ensuite faire correspondre le pattern. +// Some(..) et None sont approximativement analogue à des wrappers de Nullable +let validValue = Some(99) +let invalidValue = None + +// Dans cet exemple, match..with trouve une correspondance à "Some" et à "None", +// et affiche la valeur du "Some" en même temps. +let optionPatternMatch input = +   match input with +    | Some i -> printfn "input is an int=%d" i +    | None -> printfn "input is missing" + +optionPatternMatch validValue +optionPatternMatch invalidValue + +// ------ Affichage ------ +// Les fonctions printf/printfn sont similaires aux fonctions +// Console.Write/WriteLine de C#. +printfn "Printing an int %i, a float %f, a bool %b" 1 2.0 true +printfn "A string %s, and something generic %A" "hello" [1;2;3;4] + +// Il y a aussi les fonctions printf/sprintfn pour formater des données +// en string. C'est similaire au String.Format de C#. + +// ================================================ +// Plus sur les fonctions +// ================================================ + +// F# est un véritable langage fonctionel -- les fonctions sont des +// entités de premier ordre et peuvent êtres combinées facilement +// pour créer des constructions puissantes + +// Les modules sont utilisés pour grouper des fonctions ensemble. +// L'indentation est nécessaire pour chaque module imbriqué. +module FunctionExamples = + +    // définit un simple fonction d'addition +    let add x y = x + y + +    // usage basique d'une fonction +    let a = add 1 2 +    printfn "1+2 = %i" a + +    // partial application to "bake in" parameters (?) +    let add42 = add 42 +    let b = add42 1 +    printfn "42+1 = %i" b + +    // composition pour combiner des fonctions +    let add1 = add 1 +    let add2 = add 2 +    let add3 = add1 >> add2 +    let c = add3 7 +    printfn "3+7 = %i" c + +    // fonctions de premier ordre +    [1..10] |> List.map add3 |> printfn "new list is %A" + +    // listes de fonction et plus +    let add6 = [add1; add2; add3] |> List.reduce (>>) +    let d = add6 7 +    printfn "1+2+3+7 = %i" d + +// ================================================ +// Listes et collections +// ================================================ + +// Il y a trois types de collection ordonnée : +// * Les listes sont les collections immutables les plus basiques +// * Les tableaux sont mutables et plus efficients +// * Les séquences sont lazy et infinies (e.g. un enumerator) +// +// Des autres collections incluent des maps immutables et des sets +// plus toutes les collections de .NET + +module ListExamples = + +    // les listes utilisent des crochets +    let list1 = ["a";"b"] +    let list2 = "c" :: list1    // :: pour un ajout au début +    let list3 = list1 @ list2   // @ pour la concatenation + +    // Compréhensions des listes (aka générateurs) +    let squares = [for i in 1..10 do yield i*i] + +    //  Générateur de nombre premier +    let rec sieve = function +        | (p::xs) -> p :: sieve [ for x in xs do if x % p > 0 then yield x ] +        | []      -> [] +    let primes = sieve [2..50] +    printfn "%A" primes + +    // le pattern matching pour les listes +    let listMatcher aList = +        match aList with +        | [] -> printfn "the list is empty" +        | [first] -> printfn "the list has one element %A " first +        | [first; second] -> printfn "list is %A and %A" first second +        | _ -> printfn "the list has more than two elements" + +    listMatcher [1;2;3;4] +    listMatcher [1;2] +    listMatcher [1] +    listMatcher [] + +    // Récursion en utilisant les listes +    let rec sum aList = +        match aList with +        | [] -> 0 +        | x::xs -> x + sum xs +    sum [1..10] + +    // ----------------------------------------- +    // Fonctions de la librairie standard +    // ----------------------------------------- + +    // map +    let add3 x = x + 3 +    [1..10] |> List.map add3 + +    // filtre +    let even x = x % 2 = 0 +    [1..10] |> List.filter even + +    // beaucoup plus -- se référer à la documentation + +module ArrayExamples = + +    // les tableaux utilisent les crochets avec des barres +    let array1 = [| "a";"b" |] +    let first = array1.[0]        // accès à l'index en utilisant un point + +    // le pattern matching des tableaux est le même que celui des listes +    let arrayMatcher aList = +        match aList with +        | [| |] -> printfn "the array is empty" +        | [| first |] -> printfn "the array has one element %A " first +        | [| first; second |] -> printfn "array is %A and %A" first second +        | _ -> printfn "the array has more than two elements" + +    arrayMatcher [| 1;2;3;4 |] + +    // Fonctions de la librairie standard comme celles des listes +    [| 1..10 |] +    |> Array.map (fun i -> i+3) +    |> Array.filter (fun i -> i%2 = 0) +    |> Array.iter (printfn "value is %i. ") + +module SequenceExamples = + +    // Les séquences utilisent des accolades +    let seq1 = seq { yield "a"; yield "b" } + +    // Les séquences peuvent utiliser yield et +    // peuvent contenir des sous-sequences +    let strange = seq { +        // "yield" ajoute un élément +        yield 1; yield 2; + +        // "yield!" ajoute une sous-sequence complète +        yield! [5..10] +        yield! seq { +            for i in 1..10 do +              if i%2 = 0 then yield i }} +    // test +    strange |> Seq.toList + +    // Les séquences peuvent être créées en utilisant "unfold" +    // Voici la suite de fibonacci +    let fib = Seq.unfold (fun (fst,snd) -> +        Some(fst + snd, (snd, fst + snd))) (0,1) + +    // test +    let fib10 = fib |> Seq.take 10 |> Seq.toList +    printf "first 10 fibs are %A" fib10 + +// ================================================ +// Types de données +// ================================================ + +module DataTypeExamples = + +    // Toutes les données sont immutables par défaut + +    // Les tuples sont de simple et rapide types anonymes +    // -- Utilisons une virgule pour créer un tuple +    let twoTuple = 1,2 +    let threeTuple = "a",2,true + +    // Pattern match pour déballer +    let x,y = twoTuple  // assigne x=1 y=2 + +    // ------------------------------------ +    // Record types ont des champs nommés +    // ------------------------------------ + +    // On utilise "type" avec des accolades pour définir un type record +    type Person = {First:string; Last:string} + +    // On utilise "let" avec des accolades pour créer un record +    let person1 = {First="John"; Last="Doe"} + +    // Pattern match pour déballer +    let {First=first} = person1    // assigne first="john" + +    // ------------------------------------ +    // Union types (aka variants) ont un set de choix +    // Un seul cas peut être valide à la fois. +    // ------------------------------------ + +    // On utilise "type" avec bar/pipe pour definir un union type +    type Temp = +        | DegreesC of float +        | DegreesF of float + +    // On utilise un de ces choix pour en créér un +    let temp1 = DegreesF 98.6 +    let temp2 = DegreesC 37.0 + +    // Pattern match on all cases to unpack(?) +    let printTemp = function +       | DegreesC t -> printfn "%f degC" t +       | DegreesF t -> printfn "%f degF" t + +    printTemp temp1 +    printTemp temp2 + +    // ------------------------------------ +    // Types récursif +    // ------------------------------------ + +    // Les types peuvent être combinés récursivement de façon complexe +    // sans avoir à créer des sous-classes +    type Employee = +      | Worker of Person +      | Manager of Employee list + +    let jdoe = {First="John";Last="Doe"} +    let worker = Worker jdoe + +    // ------------------------------------ +    // Modelling with types(?) +    // ------------------------------------ + +    // Les types union sont excellents pour modelling state without using flags(?) +    type EmailAddress = +        | ValidEmailAddress of string +        | InvalidEmailAddress of string + +    let trySendEmail email = +        match email with // utilisations du pattern matching +        | ValidEmailAddress address -> ()   // envoyer +        | InvalidEmailAddress address -> () // ne pas envoyer + +    // Combiner ensemble, les types union et les types record +    // offrent une excellente fondation pour le domain driven design. +    // Vous pouvez créer des centaines de petit types qui reflèteront fidèlement +    // le domain. + +    type CartItem = { ProductCode: string; Qty: int } +    type Payment = Payment of float +    type ActiveCartData = { UnpaidItems: CartItem list } +    type PaidCartData = { PaidItems: CartItem list; Payment: Payment} + +    type ShoppingCart = +        | EmptyCart  // aucune donnée +        | ActiveCart of ActiveCartData +        | PaidCart of PaidCartData + +    // ------------------------------------ +    // Comportement natif des types +    // ------------------------------------ + +    // Les types natifs ont un comportement "prêt-à-l'emploi" des plus utiles, sans code à ajouter. +    // * Immutabilité +    // * Pretty printing au debug +    // * Egalité et comparaison +    // * Sérialisation + +    // Le Pretty printing s'utilise avec %A +    printfn "twoTuple=%A,\nPerson=%A,\nTemp=%A,\nEmployee=%A" +             twoTuple person1 temp1 worker + +    // L'égalité et la comparaison sont innés +    // Voici un exemple avec des cartes. +    type Suit = Club | Diamond | Spade | Heart +    type Rank = Two | Three | Four | Five | Six | Seven | Eight +                | Nine | Ten | Jack | Queen | King | Ace + +    let hand = [ Club,Ace; Heart,Three; Heart,Ace; +                 Spade,Jack; Diamond,Two; Diamond,Ace ] + +    // tri +    List.sort hand |> printfn "sorted hand is (low to high) %A" +    List.max hand |> printfn "high card is %A" +    List.min hand |> printfn "low card is %A" + +// ================================================ +// Les Active patterns +// ================================================ + +module ActivePatternExamples = + +    // F# a un type particulier de pattern matching nommé "active patterns" +    // où le pattern peut être parsé ou détecté dynamiquement. + +    // "banana clips" est la syntaxe pour l'active patterns + +    // par exemple, on définit un "active" pattern pour correspondre à des types "character"... +    let (|Digit|Letter|Whitespace|Other|) ch = +       if System.Char.IsDigit(ch) then Digit +       else if System.Char.IsLetter(ch) then Letter +       else if System.Char.IsWhiteSpace(ch) then Whitespace +       else Other + +    // ... et ensuite on l'utilise pour rendre la logique de parsing plus claire +    let printChar ch = +      match ch with +      | Digit -> printfn "%c is a Digit" ch +      | Letter -> printfn "%c is a Letter" ch +      | Whitespace -> printfn "%c is a Whitespace" ch +      | _ -> printfn "%c is something else" ch + +    // afficher une liste +    ['a';'b';'1';' ';'-';'c'] |> List.iter printChar + +    // ----------------------------------------- +    // FizzBuzz en utilisant les active patterns +    // ----------------------------------------- + +    // Vous pouvez créer un partial matching patterns également +    // On utilise just un underscore dans la définition, et on retourne Some si ça correspond. +    let (|MultOf3|_|) i = if i % 3 = 0 then Some MultOf3 else None +    let (|MultOf5|_|) i = if i % 5 = 0 then Some MultOf5 else None + +    // la fonction principale +    let fizzBuzz i = +      match i with +      | MultOf3 & MultOf5 -> printf "FizzBuzz, " +      | MultOf3 -> printf "Fizz, " +      | MultOf5 -> printf "Buzz, " +      | _ -> printf "%i, " i + +    // test +    [1..20] |> List.iter fizzBuzz + +// ================================================ +// Concision +// ================================================ + +module AlgorithmExamples = + +    // F# a un haut ratio signal/bruit, permettant au code de se lire +    // presque comme un véritable algorithme + +    // ------ Exemple: definir une fonction sumOfSquares ------ +    let sumOfSquares n = +       [1..n]              // 1) Prendre tous les nombres de 1 à n +       |> List.map square  // 2) Elever chacun d'entre eux au carré +       |> List.sum         // 3) Effectuer leur somme + +    // test +    sumOfSquares 100 |> printfn "Sum of squares = %A" + +    // ------ Exemple: definir un fonction de tri ------ +    let rec sort list = +       match list with +       // Si la liste est vide +       | [] -> +            []                            // on retourne une liste vide +       // si la list n'est pas vide +       | firstElem::otherElements ->      // on prend le premier élément +            let smallerElements =         // on extrait les éléments plus petits +                otherElements             // on prend les restants +                |> List.filter (fun e -> e < firstElem) +                |> sort                   // et on les trie +            let largerElements =          // on extrait les plus grands +                otherElements             // de ceux qui restent +                |> List.filter (fun e -> e >= firstElem) +                |> sort                   // et on les trie +            // On combine les 3 morceaux dans une nouvelle liste que l'on retourne +            List.concat [smallerElements; [firstElem]; largerElements] + +    // test +    sort [1;5;23;18;9;1;3] |> printfn "Sorted = %A" + +// ================================================ +// Code Asynchrone +// ================================================ + +module AsyncExample = + +    // F# inclus des fonctionnalités pour aider avec le code asynchrone +    // sans rencontrer la "pyramid of doom" +    // +    // L'exemple suivant télécharge une séquence de page web en parallèle. + +    open System.Net +    open System +    open System.IO +    open Microsoft.FSharp.Control.CommonExtensions + +    // Récupérer le contenu d'une URL de manière asynchrone +    let fetchUrlAsync url = +        async {   // Le mot clé "async" et les accolades +                  // créent un objet "asynchrone" +            let req = WebRequest.Create(Uri(url)) +            use! resp = req.AsyncGetResponse() +                // use! est un assignement asynchrone +            use stream = resp.GetResponseStream() +                // "use" déclenche automatiquement close() +                // sur les ressources à la fin du scope +            use reader = new IO.StreamReader(stream) +            let html = reader.ReadToEnd() +            printfn "finished downloading %s" url +            } + +    // une liste des sites à rapporter +    let sites = ["http://www.bing.com"; +                 "http://www.google.com"; +                 "http://www.microsoft.com"; +                 "http://www.amazon.com"; +                 "http://www.yahoo.com"] + +    // C'est parti! +    sites +    |> List.map fetchUrlAsync  // créez une liste de tâche asynchrone +    |> Async.Parallel          // dites aux tâches de tourner en parallèle +    |> Async.RunSynchronously  // démarrez les! + +// ================================================ +// .NET compatabilité +// ================================================ + +module NetCompatibilityExamples = + +    // F# peut réaliser presque tout ce que C# peut faire, et il s'intègre +    // parfaitement avec les librairies .NET ou Mono. + +    // ------- Travaillez avec les fonctions des librairies existantes  ------- + +    let (i1success,i1) = System.Int32.TryParse("123"); +    if i1success then printfn "parsed as %i" i1 else printfn "parse failed" + +    // ------- Implémentez des interfaces à la volée! ------- + +    // Créer un nouvel objet qui implémente IDisposable +    let makeResource name = +       { new System.IDisposable +         with member this.Dispose() = printfn "%s disposed" name } + +    let useAndDisposeResources = +        use r1 = makeResource "first resource" +        printfn "using first resource" +        for i in [1..3] do +            let resourceName = sprintf "\tinner resource %d" i +            use temp = makeResource resourceName +            printfn "\tdo something with %s" resourceName +        use r2 = makeResource "second resource" +        printfn "using second resource" +        printfn "done." + +    // ------- Code orienté objet ------- + +    // F# est aussi un véritable language OO. +    // Il supporte les classes, l'héritage, les méthodes virtuelles, etc. + +    // interface avec type générique +    type IEnumerator<'a> = +        abstract member Current : 'a +        abstract MoveNext : unit -> bool + +    // Classe de base abstraite avec méthodes virtuelles +    [<AbstractClass>] +    type Shape() = +        // propriétés en lecture seule +        abstract member Width : int with get +        abstract member Height : int with get +        // méthode non-virtuelle +        member this.BoundingArea = this.Height * this.Width +        // méthode virtuelle avec implémentation de la classe de base +        abstract member Print : unit -> unit +        default this.Print () = printfn "I'm a shape" + +    // classe concrète qui hérite de sa classe de base et surcharge +    type Rectangle(x:int, y:int) = +        inherit Shape() +        override this.Width = x +        override this.Height = y +        override this.Print ()  = printfn "I'm a Rectangle" + +    // test +    let r = Rectangle(2,3) +    printfn "The width is %i" r.Width +    printfn "The area is %i" r.BoundingArea +    r.Print() + +    // ------- extension de méthode  ------- + +    // Juste comme en C#, F# peut étendre des classes existantes avec des extensions de méthode. +    type System.String with +       member this.StartsWithA = this.StartsWith "A" + +    // test +    let s = "Alice" +    printfn "'%s' starts with an 'A' = %A" s s.StartsWithA + +    // ------- événements ------- + +    type MyButton() = +        let clickEvent = new Event<_>() + +        [<CLIEvent>] +        member this.OnClick = clickEvent.Publish + +        member this.TestEvent(arg) = +            clickEvent.Trigger(this, arg) + +    // test +    let myButton = new MyButton() +    myButton.OnClick.Add(fun (sender, arg) -> +            printfn "Click event with arg=%O" arg) + +    myButton.TestEvent("Hello World!") + +``` + +## Plus d'information + +Pour plus de démonstration de F#, rendez-vous sur le site [Try F#](http://www.tryfsharp.org/Learn), ou suivez la série [why use F#](http://fsharpforfunandprofit.com/why-use-fsharp/). + +Apprenez en davantage à propose de F# sur [fsharp.org](http://fsharp.org/). | 
