F Sharp (Programmiersprache) - F Sharp (programming language)

F#
F Sharp logo.svg
F#-Logozeichen
Paradigma Multiparadigma : funktional , zwingend , objektorientiert , metaprogrammierend , reflexiv , gleichzeitig
Familie ML
Entworfen von Don Syme , Microsoft Research
Entwickler Microsoft , die F# Software Foundation
Erstmals erschienen 2005 ; Vor 16 Jahren , Version 1.0 ( 2005 )
Stabile Version
5.0  Bearbeiten Sie dies auf Wikidata / 10. November 2020 ; vor 11 Monaten ( 10. November 2020 )
Vorschauversion
5.0 Vorschau / 2. April 2019 ; vor 2 Jahren ( 2019-04-02 )
Schreibdisziplin Statisch , stark , abgeleitet
Betriebssystem Plattformübergreifend : .NET , .NET Framework , Mono
Lizenz MIT-Lizenz
Dateinamenerweiterungen .fs, .fsi, .fsx, .fsscript
Webseite FSharp .org
Beeinflusst von
C# , Erlang , Haskell , ML , OCaml , Python , Scala
Beeinflusst
C# , Elm , F* , LiveScript

F# (ausgesprochen Fis ) ist eine funktionale, universelle, stark typisierte , multiparadigmatische Programmiersprache , die funktionale , imperative und objektorientierte Programmiermethoden umfasst . F# wird am häufigsten als plattformübergreifende Common Language Infrastructure (CLI)-Sprache in .NET verwendet , kann aber auch JavaScript- und GPU-Code ( Graphics Processing Unit ) generieren.

F# wird von der F# Software Foundation , Microsoft und Open-Mitwirkenden entwickelt. Ein plattformübergreifender Open-Source -Compiler für F# ist von der F# Software Foundation erhältlich. F# ist eine vollständig unterstützte Sprache in Visual Studio und JetBrains Rider . Plug-Ins, die F# unterstützen, existieren für viele weit verbreitete Editoren, insbesondere die Ionide- Erweiterung für Visual Studio Code und Integrationen für andere Editoren wie Vim und Emacs .

F# ist ein Mitglied der ML- Sprachfamilie und entstand als .NET Framework- Implementierung eines Kerns der Programmiersprache OCaml . Es wurde auch von C# , Python , Haskell , Scala und Erlang beeinflusst .

Geschichte

Versionen

Im Laufe ihrer Entwicklung hat die Sprache mehrere Versionen durchlaufen:

Ausführung Sprachspezifikation Datum Plattformen Laufzeit
F# 1.x Mai 2005 Fenster .NET 1.0 - 3.5
F# 2.0 August 2010 April 2010 Linux , macOS , Windows .NET 2.0 - 4.0, Mono
F# 3.0 November 2012 August 2012 Linux , macOS , Windows ;
JavaScript , GPU
.NET 2.0 - 4.5, Mono
F# 3.1 November 2013 Oktober 2013 Linux , macOS , Windows ;
JavaScript , GPU
.NET 2.0 - 4.5, Mono
F# 4.0 Januar 2016 Juli 2015
F# 4.1 Mai 2018 März 2017 Linux , macOS , Windows ,

JavaScript , GPU

.NET 3.5 - 4.6.2, .NET Core , Mono
F# 4.5 August 2018 Linux , macOS , Windows ,

JavaScript , GPU

.NET 4.5 - 4.7.2, .NET Core SDK 2.1.400
F# 4.6 März 2019 Linux , macOS , Windows ,

JavaScript , GPU

.NET 4.5 - 4.7.2, .NET Core SDK 2.2.300
F# 4,7 September 2019 Linux , macOS , Windows ,

JavaScript , GPU

.NET 4.5 - 4.8, .NET Core SDK 3.0.100
F# 5.0 November 2020 Linux , macOS , Windows ,

JavaScript , GPU

.NET- SDK 5.0.100

Sprachentwicklung

F# verwendet einen offenen Entwicklungs- und Engineering-Prozess. Der Sprachentwicklungsprozess wird von Don Syme von Microsoft Research als wohlwollender Diktator für das Leben (BDFL) für das Sprachdesign zusammen mit der F# Software Foundation geleitet. Frühere Versionen der Sprache F# wurden von Microsoft und Microsoft Research in einem geschlossenen Entwicklungsprozess entwickelt.

F# stammt von Microsoft Research , Cambridge, UK. Die Sprache wurde ursprünglich von Don Syme entworfen und implementiert , laut denen im fsharp-Team das F für "Fun" steht. Andrew Kennedy trug zum Entwurf von Maßeinheiten bei . Die Visual F#-Tools für Visual Studio werden von Microsoft entwickelt. Die F# Software Foundation hat den F#-Open-Source-Compiler und -Tools entwickelt und dabei die Open-Source-Compiler-Implementierung des Microsoft Visual F#-Tools-Teams integriert.

Zusammenfassung der Versionen
Funktionen hinzugefügt
F# 1.0
  • Funktionale Programmierung
  • Diskriminierte Gewerkschaften
  • Aufzeichnungen
  • Tupel
  • Musterabgleich
  • Abkürzungen eingeben
  • Objekt orientierte Programmierung
  • Strukturen
  • Signaturdateien
  • Skriptdateien
  • Imperative Programmierung
  • Module (keine Funktore)
  • Verschachtelte Module
  • .NET-Interoperabilität
F# 2.0
  • Aktive Muster
  • Maßeinheiten
  • Sequenzausdrücke
  • Asynchrone Programmierung
  • Agentenprogrammierung
  • Erweiterungsmitglieder
  • Benannte Argumente
  • Optionale Argumente
  • Array-Slicing
  • Zitate
  • Native Interoperabilität
  • Berechnungsausdrücke
F# 3.0
  • Typanbieter
  • LINQ-Abfrageausdrücke
  • CLIMutable-Attribut
  • Strings in dreifachen Anführungszeichen
  • Auto-Eigenschaften
  • Bereitgestellte Maßeinheiten
F# 3.1
  • Benannte Unionstypfelder
  • Erweiterungen zum Array-Slicing
  • Verbesserungen der Typinferenz
F# 4.0
  • Printf auf Einheitswerten
  • Initialisierer für Erweiterungseigenschaften
  • Nicht null bereitgestellte Typen
  • Primärkonstruktoren als Funktionen
  • Statische Parameter für bereitgestellte Methoden
  • Printf-Interpolation
  • Erweiterte #if Grammatik
  • Tailcall-Attribut
  • Mehrere Schnittstelleninstanzen
  • Optionale Typargumente
  • Params-Wörterbücher
F# 4.1
  • Strukturtupel, die mit C#-Tupeln interagieren
  • Strukturanmerkungen für Datensätze
  • Strukturanmerkungen für im Einzelfall diskriminierte Gewerkschaften
  • Unterstriche in numerischen Literalen
  • Argumentattribute für Anruferinformationen
  • Ergebnistyp und einige grundlegende Ergebnisfunktionen
  • Gegenseitig referenzierende Typen und Module innerhalb derselben Datei
  • Implizite "Module"-Syntax bei Modulen mit gemeinsamem Namen als Typ
  • Byref-Rückgaben, die verbrauchende C#-Ref-Rückgabemethoden unterstützen
  • Verbesserungen bei Fehlermeldungen
  • Unterstützung für 'fixiert'
F# 4.5
  • Versionierungsausrichtung von Binärdatei, Paket und Sprache
  • Unterstützung für 'Span<T>' und verwandte Typen
  • Möglichkeit, 'byref'-Retouren zu erstellen
  • Der 'voidptr'-Typ
  • Die Typen 'inref<'T>' und 'outref<'T>' zur Darstellung von schreibgeschützten und schreibgeschützten 'byref's
  • 'IsByRefLike'-Strukturen
  • 'IsReadOnly'-Strukturen
  • Unterstützung von Erweiterungsmethoden für 'byref<'T>'/'inref<'T>'/'outref<'T>'
  • 'Spiel!' Schlüsselwort in Berechnungsausdrücken
  • Entspannter Upcast mit 'Yield' in F#-Seq-/Listen-/Array-Ausdrücken
  • Entspannte Einrückung mit Listen- und Array-Ausdrücken
  • Als öffentlich ausgegebene Aufzählungsfälle
F# 4,7
  • Implizite Renditen
  • Kein doppelter Unterstrich mehr erforderlich
  • Einrückungslockerungen für Parameter, die an Konstruktoren und statische Methoden übergeben werden
  • 'nameof'-Funktion
  • Statische Klassen öffnen
F# 5.0
  • FSharp.Core zielt jetzt nur auf Netstandard2.0 ab
  • Paketverweise in F#-Skripten
  • Unterstützung für Jupyter-, nteract- und VSCode-Notebooks
  • String-Interpolation
  • Unterstützung für nameof
  • Open Type-Deklarationen
  • Verbessertes Schneiden
  • Verbesserungen bei F#-Zitaten
  • Anwendbare Berechnungsausdrücke
  • Verbesserte Stack-Traces in F# async und anderen Berechnungsausdrücken
  • Verbesserte .NET-Interop
  • Verbesserte Karten- und Set-Leistung in FSharp.Core
  • Verbesserte Compilerleistung
  • Verbesserte Compileranalyse für Bibliotheksautoren

Sprachübersicht

Funktionale Programmierung

F# ist eine funktionale Programmiersprache. Das bedeutet, dass in F# Funktionen stärker betont werden als Objekte und Strukturen und andere traditionelle Programmierkonstrukte. F# ist eine stark typisierte funktionale First-Sprache, die den Typrückschluss verwendet . F# lässt auch explizite Typanmerkungen zu und erfordert sie in einigen Situationen.

F# ist eine ausdrucksbasierte Sprache, die Eager-Evaluierung und in einigen Fällen auch Lazy-Evaluation verwendet . Jede Anweisung in F#, einschließlich ifAusdrücken, tryAusdrücken und Schleifen, ist ein zusammensetzbarer Ausdruck mit einem statischen Typ. Funktionen und Ausdrücke, die keinen Wert zurückgeben, haben den Rückgabetyp unit. F# verwendet das letSchlüsselwort zum Binden von Werten an einen Namen. Zum Beispiel:

let x = 3 + 4

bindet den Wert 7an den Namen x.

Neue Typen werden mit dem typeSchlüsselwort definiert . Für die funktionale Programmierung bietet F# die Typen tuple , record , diskriminated union , list , option und result . Ein Tupel stellt eine Menge von n Werten dar, wobei n 0 ist. Der Wert n wird als Anzahl des Tupels bezeichnet. Ein 3-Tupel würde als dargestellt werden (A, B, C), wobei A, B und C Werte von möglicherweise unterschiedlichen Typen sind. Ein Tupel kann nur dann zum Speichern von Werten verwendet werden, wenn die Anzahl der Werte zur Entwurfszeit bekannt ist und während der Ausführung konstant bleibt.

Ein Datensatz ist ein Typ, bei dem die Datenelemente benannt sind. Hier ist ein Beispiel für die Datensatzdefinition:

 type R = 
        { Name : string 
         Age : int }

Datensätze können als . Das Schlüsselwort wird verwendet, um eine Kopie eines Datensatzes zu erstellen, wie in , wodurch ein neuer Datensatz erstellt wird, indem der Wert des Felds kopiert und geändert wird (vorausgesetzt, der im letzten Beispiel erstellte Datensatz hieß ). let r = { Name="AB"; Age=42 }with{ r with Name="CD" }rNamer

Ein diskriminierter Unionstyp ist eine typsichere Version von C unions . Zum Beispiel,

 type A = 
    | UnionCaseX of string
    | UnionCaseY of int

Werte des Unionstyps können beiden Unionsfällen entsprechen. Die Typen der Werte, die von jedem Unionsfall getragen werden, sind in der Definition jedes Falles enthalten.

Der Listentyp ist eine unveränderliche verknüpfte Liste, die entweder mit einer Notation ( ist der Kontraoperator ) oder einer Kurzform als dargestellt wird . Eine leere Liste wird geschrieben . Der Optionstyp ist ein diskriminierter Unionstyp mit Auswahlmöglichkeiten oder . F#-Typen können generisch sein , die als generische .NET-Typen implementiert sind. head::tail::[item1; item2; item3][]Some(x)None

F# unterstützt Lambda-Funktionen und Closures . Alle Funktionen in F# sind erstklassige Werte und unveränderlich. Funktionen können gecurry werden . Da es sich um erstklassige Werte handelt, können Funktionen als Argumente an andere Funktionen übergeben werden. Wie andere funktionale Programmiersprachen ermöglicht F# die Funktionskomposition (Informatik) mit den Operatoren >>und <<.

F# bietet Sequenzausdrücke , die eine Sequenzseq { ... }, eine Liste[ ... ]oder ein Array[| ... |]durch Code definieren, der Werte generiert. Zum Beispiel,

 seq { for b in 0 .. 25 do
           if b < 15 then
               yield b*b }

bildet eine Folge von Zahlenquadraten von 0 bis 14 durch Herausfiltern von Zahlen aus dem Zahlenbereich von 0 bis 25. Folgen sind Generatoren – Werte werden nach Bedarf generiert (dh träge ausgewertet ) – während Listen und Arrays eifrig ausgewertet werden .

F# verwendet den Mustervergleich , um Werte an Namen zu binden. Der Mustervergleich wird auch beim Zugriff auf diskriminierte Vereinigungen verwendet – der Wert der Vereinigung wird mit Musterregeln abgeglichen und eine Regel wird ausgewählt, wenn eine Übereinstimmung erfolgreich ist. F# unterstützt auch aktive Muster als eine Form des erweiterbaren Mustervergleichs. Es wird beispielsweise verwendet, wenn mehrere Möglichkeiten zum Abgleichen eines Typs vorhanden sind.

F# unterstützt eine allgemeine Syntax zum Definieren von Kompositionsberechnungen namens Berechnungsausdrücke . Sequenzausdrücke, asynchrone Berechnungen und Abfragen sind besondere Arten von Berechnungsausdrücken. Berechnungsausdrücke sind eine Implementierung desMonadenmusters.

Imperative Programmierung

F#-Unterstützung für die imperative Programmierung umfasst

  • for Schleifen
  • while Schleifen
  • Arrays , erstellt mit der [| ... |]Syntax
  • Hash-Tabelle , erstellt mit der dict [ ... ]Syntax oder dem System.Collections.Generic.Dictionary<_,_>Typ.

Werte und Datensatzfelder können auch als gekennzeichnet werden mutable. Zum Beispiel:

// Define 'x' with initial value '1'
let mutable x = 1
// Change the value of 'x' to '3'
x <- 3

Außerdem unterstützt F# den Zugriff auf alle CLI-Typen und -Objekte, wie z. B. diejenigen, die im System.Collections.GenericNamespace definiert sind, der zwingende Datenstrukturen definiert.

Objekt orientierte Programmierung

Wie andere Common Language Infrastructure (CLI)-Sprachen kann F# CLI-Typen durch objektorientierte Programmierung verwenden. Die F#-Unterstützung für die objektorientierte Programmierung in Ausdrücken umfasst:

  • Punktnotation, z. x.Name
  • Objektausdrücke, z. { new obj() with member x.ToString() = "hello" }
  • Objektkonstruktion, z. new Form()
  • Typprüfungen, z. x :? string
  • Typzwang, z. x :?> string
  • Benannte Argumente, z. x.Method(someArgument=1)
  • Benannte Setter, z. new Form(Text="Hello")
  • Optionale Argumente, z. x.Method(OptionalArgument=1)

Unterstützung für objektorientierte Programmierung in Mustern umfasst

  • Typprüfungen, z. :? string as s
  • Aktive Muster, die über Objekttypen definiert werden können

F#-Objekttypdefinitionen können Klassen-, Struktur-, Schnittstellen-, Enumerations- oder Delegattypdefinitionen sein, die den Definitionsformularen in C# entsprechen . Hier ist beispielsweise eine Klasse mit einem Konstruktor, der einen Namen und ein Alter annimmt und zwei Eigenschaften deklariert.

/// A simple object type definition
type Person(name : string, age : int) =
    member x.Name = name
    member x.Age = age

Asynchrone Programmierung

F# unterstützt die asynchrone Programmierung durch asynchrone Workflows . Ein asynchroner Workflow ist als eine Folge von Befehlen in einem definiert async{ ... }, wie in

let asynctask = 
    async { let req = WebRequest.Create(url)
            let! response = req.GetResponseAsync()
            use stream = response.GetResponseStream()
            use streamreader = new System.IO.StreamReader(stream)
            return streamreader.ReadToEnd() }

Das let!gibt an, dass der Ausdruck auf der rechten Seite (das Abrufen der Antwort) asynchron erfolgen soll, der Fluss jedoch nur fortgesetzt werden soll, wenn das Ergebnis verfügbar ist. Mit anderen Worten, aus Sicht des Codeblocks ist es so, als ob das Erhalten der Antwort ein blockierender Aufruf wäre, während der Thread aus Sicht des Systems nicht blockiert wird und zur Verarbeitung anderer Flüsse verwendet werden kann während das für dieses benötigte Ergebnis nicht verfügbar ist.

Der asynchrone Block kann unter Verwendung der Async.RunSynchronouslyFunktion aufgerufen werden . Mehrere asynchrone Blöcke können parallel ausgeführt werden, indem die Async.ParallelFunktion verwendet wird, die eine Liste von asyncObjekten (im Beispiel asynctaskein asynchrones Objekt) nimmt und ein weiteres asynchrones Objekt erstellt, um die Aufgaben in den Listen parallel auszuführen. Das resultierende Objekt wird mit aufgerufen Async.RunSynchronously. Die Inversion der Steuerung in F# folgt diesem Muster.

Parallele Programmierung

Die parallele Programmierung wird teilweise durch die Async.Parallel, Async.Startund andere Operationen unterstützt, die asynchrone Blöcke parallel ausführen.

Parallele Programmierung wird auch durch die Array.Parallelfunktionalen Programmieroperatoren in der F#-Standardbibliothek, die direkte Verwendung des System.Threading.TasksTask-Programmiermodells, die direkte Verwendung von .NET-Thread-Pools und .NET-Threads und durch dynamische Übersetzung von F#-Code in alternative parallele Ausführungs-Engines wie z GPU- Code.

Maßeinheiten

Das F#-Typsystem unterstützt die Überprüfung von Maßeinheiten auf Zahlen. Die Maßeinheitenfunktion ist in die F#-Typinferenz integriert, um minimale Typanmerkungen im Benutzercode zu erfordern.

Metaprogrammierung

F# ermöglicht einige Formen der Syntaxanpassung über Metaprogrammierung , um die Einbettung benutzerdefinierter domänenspezifischer Sprachen in die F#-Sprache zu unterstützen, insbesondere durch Berechnungsausdrücke.

F# enthält eine Funktion für die Laufzeit-Metaprogrammierung, die als Zitate bezeichnet wird. Ein Zitatausdruck wird zu einer abstrakten Syntaxbaumdarstellung der F#-Ausdrücke ausgewertet. Ebenso kann auf Definitionen, die mit dem [<ReflectedDefinition>]Attribut gekennzeichnet sind, in ihrer Zitatform zugegriffen werden. F#-Zitate werden für verschiedene Zwecke verwendet, einschließlich zum Kompilieren von F#-Code in JavaScript- und GPU- Code. (Zitate stellen ihre F#-Codeausdrücke als Daten für die Verwendung durch andere Teile des Programms dar, erfordern jedoch, dass es sich um syntaktisch korrekten F#-Code handelt).

Informationsreiche Programmierung

Mit F# 3.0 wurde eine Form der Metaprogrammierung zur Kompilierzeit durch statisch erweiterbare Typgenerierung eingeführt, die als F#-Typanbieter bezeichnet wird. Mit F#-Typanbietern können der F#-Compiler und die F#-Tools um Komponenten erweitert werden, die dem Compiler zur Kompilierzeit bei Bedarf Typinformationen bereitstellen. F#-Typ-Provider wurden verwendet, um auf skalierbare Weise stark typisierten Zugriff auf verbundene Informationsquellen zu ermöglichen, einschließlich des Freebase- Wissensgraphen.

In F# 3.0 werden die F#-Zitat- und Berechnungsausdrucksfunktionen kombiniert, um LINQ- Abfragen zu implementieren . Zum Beispiel:

// Use the OData type provider to create types that can be used to access the Northwind database.
open Microsoft.FSharp.Data.TypeProviders

type Northwind = ODataService<"http://services.odata.org/Northwind/Northwind.svc">
let db = Northwind.GetDataContext()

// A query expression.
let query1 = query { for customer in db.Customers do
                     select customer }

Die Kombination aus Typanbietern, Abfragen und stark typisierter funktionaler Programmierung wird als informationsreiche Programmierung bezeichnet .

Agentenprogrammierung

F# unterstützt eine Variation des Actor- Programmiermodells durch die In-Memory-Implementierung von leichtgewichtigen asynchronen Agenten. Der folgende Code definiert beispielsweise einen Agenten und postet 2 Nachrichten:

let counter =
    MailboxProcessor.Start(fun inbox ->
        let rec loop n =
            async { do printfn "n = %d, waiting..." n
                    let! msg = inbox.Receive()
                    return! loop(n+msg) }
        loop 0)

Entwicklungswerkzeuge

  • Visual Studio mit den installierten Visual F#-Tools von Microsoft kann zum Erstellen, Ausführen und Debuggen von F#-Projekten verwendet werden. Die Visual F#-Tools umfassen eine von Visual Studio gehostete Read-Eval-Print-Loop (REPL) interaktive Konsole, die F#-Code während des Schreibens ausführen kann. Visual Studio für Mac unterstützt auch vollständig F#-Projekte.
  • Visual Studio Code enthält vollständige Unterstützung für F# über die Ionide-Erweiterung .
  • F# kann mit jedem Texteditor entwickelt werden. Spezifische Unterstützung gibt es in Editoren wie Emacs .
  • JetBrains Rider ist ab Release 2019.1 für die Entwicklung von F#-Code optimiert.
  • LINQPad unterstützt F# seit Version 2.x.

Anwendungsbereiche

F# ist eine universelle Programmiersprache .

Web Programmierung

Der SAFE Stack ist ein End-to-End-F#-Stack zur Entwicklung von Webanwendungen. Es verwendet ASP.NET Core auf der Serverseite und Fable auf der Clientseite.

Eine alternative End-to-End-F#-Option ist das WebSharper- Framework.

Plattformübergreifende App-Entwicklung

F# kann zusammen mit den Visual Studio-Tools für Xamarin verwendet werden , um Apps für iOS und Android zu entwickeln . Die Fabulous- Bibliothek bietet eine komfortablere funktionale Schnittstelle.

Analytische Programmierung

F# wird unter anderem für quantitative Finanzprogrammierung, Energiehandel und Portfoliooptimierung, maschinelles Lernen, Business Intelligence und Social Gaming auf Facebook verwendet .

In den 2010er Jahren wurde F# als optimierte Alternative zu C# positioniert . Die Skriptfähigkeit von F# und die Sprachkompatibilität mit allen Microsoft-Produkten haben es bei Entwicklern beliebt gemacht.

Skripting

F# kann als Skriptsprache verwendet werden, hauptsächlich für das Desktop- Lese-Evaluieren-Drucken-Schleifen (REPL).

Open-Source-Community

Die F# -Open-Source- Community umfasst die F# Software Foundation und die F# Open Source Group auf GitHub . Beliebte Open-Source-F#-Projekte sind:

  • Fable , ein F#-zu-JavaScript-Transpiler basierend auf Babel .
  • Paket , ein alternativer Paketmanager für .NET, der weiterhin NuGet- Repositorys verwenden kann, aber über eine zentralisierte Versionsverwaltung verfügt.
  • FAKE , ein F#-freundliches Build-System.
  • Giraffe , eine funktionsorientierte Middleware für ASP.NET Core .
  • Suave , eine leichtgewichtige Webserver- und Webentwicklungsbibliothek.

Kompatibilität

F# verfügt über einen Legacy-"ML-Kompatibilitätsmodus", der Programme, die grob in einer großen Teilmenge von OCaml geschrieben wurden, ohne Funktoren, Objekte, polymorphe Varianten oder andere Zusätze direkt kompilieren kann.

Beispiele

Es folgen ein paar kleine Beispiele:

// This is a comment for a sample hello world program.
printfn "Hello World!"

Eine Person-Klasse mit einem Konstruktor, der einen Namen und ein Alter und zwei unveränderliche Eigenschaften annimmt.

/// This is a documentation comment for a type definition.
type Person(name : string, age : int) =
    member x.Name = name
    member x.Age = age
    
/// class instantiation
let mrSmith = Person("Smith", 42)

Ein einfaches Beispiel, das häufig verwendet wird, um die Syntax funktionaler Sprachen zu demonstrieren, ist die Fakultätsfunktion für nicht negative 32-Bit-Ganzzahlen, hier in F# gezeigt:

/// Using pattern matching expression
let rec factorial n =
    match n with
    | 0 -> 1
    | _ -> n * factorial (n - 1)

/// For a single-argument functions there is syntactic sugar (pattern matching function):
let rec factorial = function 
    | 0 -> 1 
    | n -> n * factorial (n - 1)
    
/// Using fold and range operator
let factorial n = [1..n] |> Seq.fold (*) 1

Iterationsbeispiele:

/// Iteration using a 'for' loop
let printList lst = 
    for x in lst do
        printfn "%d" x

/// Iteration using a higher-order function
let printList2 lst = 
    List.iter (printfn "%d") lst

/// Iteration using a recursive function and pattern matching
let rec printList3 lst =
    match lst with
    | [] -> ()
    | h :: t ->
        printfn "%d" h
        printList3 t

Fibonacci-Beispiele:

/// Fibonacci Number formula
let fib n =
    let rec g n f0 f1 =
        match n with
        | 0 -> f0
        | 1 -> f1
        | _ -> g (n - 1) f1 (f0 + f1)
    g n 0 1

/// Another approach - a lazy infinite sequence of Fibonacci numbers
let fibSeq = Seq.unfold (fun (a,b) -> Some(a+b, (b, a+b))) (0,1)

// Print even fibs
[1 .. 10]
|> List.map     fib
|> List.filter  (fun n -> (n % 2) = 0)
|> printList

// Same thing, using a list expression
[ for i in 1..10 do
    let r = fib i
    if r % 2 = 0 then yield r ]
|> printList

Ein Beispielprogramm für Windows Forms:

// Open the Windows Forms library
open System.Windows.Forms

// Create a window and set a few properties
let form = new Form(Visible=true, TopMost=true, Text="Welcome to F#")

// Create a label to show some text in the form
let label =
    let x = 3 + (4 * 5)
    new Label(Text = sprintf "x = %d" x)

// Add the label to the form
form.Controls.Add(label)

// Finally, run the form
[<System.STAThread>]
Application.Run(form)

Beispiel für asynchrone parallele Programmierung (parallele CPU- und I/O-Tasks):

/// A simple prime number detector
let isPrime (n:int) =
   let bound = int (sqrt (float n))
   seq {2 .. bound} |> Seq.forall (fun x -> n % x <> 0)

// We are using async workflows
let primeAsync n =
    async { return (n, isPrime n) }

/// Return primes between m and n using multiple threads
let primes m n =
    seq {m .. n}
        |> Seq.map primeAsync
        |> Async.Parallel
        |> Async.RunSynchronously
        |> Array.filter snd
        |> Array.map fst

// Run a test
primes 1000000 1002000
    |> Array.iter (printfn "%d")

Siehe auch

Anmerkungen

Verweise

  • Syme, Don ; Granicz, Adam; Cisternino, Antonio (2007), Experte F# , Apress
  • Harrop, Jon (2010), Visual F# 2010 für Technische Informatik , Flying Frog Consultancy
  • Pickering, Robert (2007), Grundlagen von F# , Apress
  • Smith, Chris (2009), Programmierung von F# , O'Reilly
  • Petricek, Tomas (2009), Real World Functional Programming mit Beispielen in F# und C# , Manning Publications
  • Hansen, Michael; Rischel, Hans (2013), Funktionale Programmierung mit F# , Cambridge University Press
  • Astborg, Johan (2013), F# für Quantitative Finance , Packt Publishing
  • Lundin, Mikael (2015), Testen mit F# , Packt Publishing

Externe Links