Linguaggio F#: suggerimenti per i principianti [chiuso]
-
09-06-2019 - |
Domanda
Sembra che qui in StackOveflow ci sia un gruppo di F# appassionati.
Mi piacerebbe conoscere meglio questa lingua, quindi, a parte il teoria della programmazione funzionale, puoi indicarmi i punti di partenza migliori per iniziare a utilizzare il linguaggio F#?Intendo tutorial, how-to, ma soprattutto esempi funzionanti per avere la possibilità di iniziare a fare qualcosa e divertirsi con la lingua.
Molte grazie
Andrea
Soluzione
Non per prostituirmi orribilmente, ma ho scritto un paio di post di panoramica di F# sul mio blog Qui E Qui.Chris Smith (un membro del team F# di MS) ha scritto un articolo intitolato "F# in 20 minuti" - parte 1 E parte 2.
Tieni presente che devi fare attenzione poiché l'ultimo CTP di F# (versione 1.9.6.0) presenta alcune modifiche importanti rispetto alle versioni precedenti, quindi alcuni esempi/tutorial disponibili potrebbero non funzionare senza modifiche.
Ecco un rapido elenco di alcune cose interessanti, forse posso darti io stesso alcuni suggerimenti che sono chiaramente molto breve e probabilmente non eccezionale ma spero che ti dia qualcosa con cui giocare!: -
Prima nota: la maggior parte degli esempi su Internet presuppone che la "sintassi leggera" sia attivata.Per ottenere ciò utilizzare la seguente riga di codice: -
#light
Ciò evita di dover inserire determinate parole chiave presenti per la compatibilità con OCaml e di dover terminare ogni riga con punto e virgola.Tieni presente che l'utilizzo di questa sintassi significa che il rientro definisce l'ambito.Ciò risulterà chiaro negli esempi successivi, i quali si basano tutti sull'attivazione della sintassi leggera.
Se stai utilizzando la modalità interattiva devi terminare tutte le istruzioni con il doppio punto e virgola, ad esempio:-
> #light;;
> let f x y = x + y;;
val f : int -> int -> int
> f 1 2;;
val it : int = 3
Tieni presente che la modalità interattiva restituisce un risultato 'val' dopo ogni riga.Ciò fornisce informazioni importanti sulle definizioni che stiamo creando, ad esempio 'val f :int -> int -> int' indica che una funzione che accetta due int restituisce un int.
Tieni presente che solo in modalità interattiva dobbiamo terminare le righe con punto e virgola, quando in realtà definiamo il codice F# ne siamo liberi :-)
Le funzioni vengono definite utilizzando la parola chiave "let".Questa è probabilmente la parola chiave più importante in tutto F# e la utilizzerai molto.Per esempio:-
let sumStuff x y = x + y
let sumStuffTuple (x, y) = x + y
Possiamo chiamare queste funzioni così: -
sumStuff 1 2
3
sumStuffTuple (1, 2)
3
Nota che ci sono due modi diversi per definire le funzioni qui: puoi separare i parametri tramite spazi bianchi o specificare i parametri in "tuple" (ad es.valori tra parentesi separati da virgole).La differenza è che possiamo usare l'applicazione parziale di funzioni per ottenere funzioni che richiedono meno dei parametri richiesti utilizzando il primo approccio e non con il secondo.Per esempio.:-
let sumStuff1 = sumStuff 1
sumStuff 2
3
Nota che stiamo ottenendo una funzione dall'espressione 'sumStuff 1'.Quando possiamo trasferire le funzioni con la stessa facilità dei dati a cui ci si riferisce come al linguaggio con "funzioni di prima classe", questa è una parte fondamentale di qualsiasi linguaggio funzionale come F#.
La corrispondenza dei modelli è dannatamente interessante, è fondamentalmente come un'istruzione di cambio sugli steroidi (sì, ho preso quella frase da un altro F#-ist :-).Puoi fare cose come: -
let someThing x =
match x with
| 0 -> "zero"
| 1 -> "one"
| 2 -> "two"
| x when x < 0 -> "negative = " + x.ToString()
| _ when x%2 = 0 -> "greater than two but even"
| _ -> "greater than two but odd"
Nota: usiamo il simbolo '_' quando vogliamo trovare una corrispondenza su qualcosa, ma l'espressione che stiamo restituendo non dipende dall'input.
Possiamo abbreviare la corrispondenza dei modelli utilizzando le istruzioni if, elif e else come richiesto: -
let negEvenOdd x = if x < 0 then "neg" elif x % 2 = 0 then "even" else "odd"
Gli elenchi F# (che sono implementati come elenchi collegati di seguito) possono essere manipolati in questo modo: -
let l1 = [1;2;3]
l1.[0]
1
let l2 = [1 .. 10]
List.length l2
10
let squares = [for i in 1..10 -> i * i]
squares
[1; 4; 9; 16; 25; 36; 49; 64; 81; 100]
let square x = x * x;;
let squares2 = List.map square [1..10]
squares2
[1; 4; 9; 16; 25; 36; 49; 64; 81; 100]
let evenSquares = List.filter (fun x -> x % 2 = 0) squares
evenSqares
[4; 16; 36; 64; 100]
Nota che la funzione List.map "mappa" la funzione quadrata sull'elenco da 1 a 10, ovveroapplica la funzione a ciascun elemento.List.filter 'filtra' un elenco restituendo solo i valori nell'elenco che passano la funzione di predicato fornita.Nota anche la sintassi 'fun x -> f': questa è la lambda F#.
Si noti che in tutto questo non abbiamo definito alcun tipo: il compilatore/interprete F# "deduce" i tipi, ad es.risolve ciò che desideri dall'utilizzo.Per esempio:-
let f x = "hi " + x
Qui il compilatore/interprete determinerà che x è una stringa poiché stai eseguendo un'operazione che richiede che x sia una stringa.Determina inoltre che anche il tipo restituito sarà una stringa.
Quando c'è ambiguità il compilatore fa delle ipotesi, ad esempio: -
let f x y = x + y
Qui xey potrebbero essere diversi tipi, ma il compilatore utilizza per impostazione predefinita int.Se vuoi definire i tipi puoi usare l'annotazione del tipo: -
let f (x:string) y = x + y
Nota anche che abbiamo dovuto racchiudere x:string tra parentesi, spesso dobbiamo farlo per separare parti di una definizione di funzione.
Due operatori davvero utili e molto utilizzati in F# sono rispettivamente gli operatori pipe forward e composizione della funzione |> e >>.
Definiamo |> così:-
let (|>) x f = f x
Nota che puoi definire gli operatori in F#, questo è davvero interessante :-).
Ciò ti consente di scrivere le cose in modo più chiaro, ad esempio: -
[1..10] |> List.map (fun x -> x * x) |> List.filter (fun x -> x % 2 = 0)
Ti permetterà di ottenere i primi 10 quadrati pari.Questo è più chiaro di: -
List.filter (fun x -> x % 2 = 0) (List.map (fun x -> x * x) [1..10])
Beh, almeno penso di sì :-)
La composizione della funzione definita dall'operatore >> è definita come segue: -
let (>>) f g x = g(f(x))
Cioè.si inoltra un'operazione solo il parametro della prima funzione rimane non specificato.Questo è utile in quanto puoi fare quanto segue: -
let mapFilter = List.map (fun x -> x * x) >> List.filter (fun x -> x % 2 = 0)
Qui mapFilter accetterà un elenco e un input e restituirà l'elenco filtrato come prima.È una versione abbreviata di: -
let mapFilter = l |> List.map (fun x -> x * x) |> List.filter (fun x -> x % 2 = 0)
Se vogliamo scrivere funzioni ricorsive dobbiamo definire la funzione come ricorsiva inserendo 'rec' dopo let.Esempi di seguito.
Alcune cose interessanti: -
Fattoriale
let rec fact x = if x <= 1 then 1 else x * fact (x-1)
ennesimo numero di Fibonacci
let rec fib n = if n <= 1 then n else fib (n-1) + fib (n-2)
FizzBuzz
let (/%) x y = x % y = 0
let fb = function
| x when x /% 15 -> "FizzBuzz"
| x when x /% 3 -> "Fizz"
| x when x /% 5 -> "Buzz"
| x -> x.ToString()
[1..100] |> List.map (fb >> printfn "%s")
Comunque questo è un molto breve panoramica, spero che aiuti un po'!!
Altri suggerimenti
Senza dubbio dovreste acquistare l'eccellente libro di Don Syme "Expert F#".Il libro è scritto molto bene ed è adatto sia ai principianti che agli esperti.In esso troverai sia materiale introduttivo che materiale molto più impegnativo.Con quasi 600 pagine ha un buon rapporto qualità-prezzo.
Ho scoperto che mi ha insegnato molte tecniche utili per scrivere C# più funzionali, oltre a fornire tutto il materiale di riferimento necessario per iniziare a scrivere applicazioni F# ospitate da Windows.
Il libro è pubblicato da Apress e ha un sito web di accompagnamento all'indirizzo:http://www.expert-fsharp.com/default.aspx
@kronoz - beh, grazie mille per la tua lunga risposta, è davvero un buon punto di partenza.Seguirò i tuoi consigli e cercherò il libro menzionato da @vecstasy.
ora, lasciami andare a scrivere il codice :-)
let thanksalot = "thanks a lot"
printfn "%s" (thanksalot);;
Ho letto Programmazione funzionale del mondo reale
Con esempi in Fa# e C# di: Tomas Petricek
Finora lo trovo molto bravo nell'insegnare i concetti di F# mostrando a lato le implementazioni in C#.Ottimo per i programmatori OO.
Dai un'occhiata a Centro per sviluppatori F#.C'è anche hubFS, un forum dedicato a F#.
Se disponi della versione CTP corrente in Visual Studio, puoi creare un progetto Tutorial F#, che ti fornisce un Tutorial.fs, contenente esattamente ciò che suggerisce il nome.
Questo tutorial punta anche a una raccolta più ampia di file Esempi di F# in Microsoft.
Inoltre, è in corso un progetto di esempi F# su CodePlex.
Spero che questo ti aiuti,
Michiel