F#, Funktionale Programmierung mit .NET, Teil 3

23. Februar 2008 – 16:32 von Andreas

In diesem Teil werden folgende Themen behandelt: Anonyme Funktionen, Listen

Zuerst aber die Lösung zur zuletzt gestellten Aufgabe (Definieren eines Fakultät-Operators !):

  1. // Definieren des Operators
  2. let rec (!) (x : int) =
  3.     if x <= 1 then // Rekursionsbremse
  4.         1
  5.     else
  6.         x * !(x-1) // rekursiver Aufruf
  7.  
  8. let endresult = !5
  9. printfn "Die fakultaet von 5 ist %i" endresult

Anonyme Funktionen

Anonyme Funktionen sind Funktionen, bei denen kein Funktionsname benötigt wird. Sie werden auch als lambda functions oder auch nur als lambdas bezeichnet. Ein Anwendungsbeispiel für eine anonyme Funktion wäre z.B. wenn eine Funktion selbst als Argument für eine andere Funktion dienen soll. In diesem Fall benötigt man normal nicht einen extra Funktionsnamen für die zu übergebende Funktion. Eine anonyme Funktion wird in F# mit dem Schlüsselwort “fun” definiert:

  1. // ergebnis enthaelt nicht die funktion x * y,
  2. // sondern sofort das ergebnis der Multiplikation
  3. // von 2 und 4. Bei x und y handelt es sich um die
  4. // Parameter. Der Pfeil -&gt; leitet dann die eigentliche
  5. // Operation ein.
  6. let ergebnis = (fun x y -&gt; x * y) 2 4
  7. printfn "2*4 ist %i" ergebnis

Eine weiter Möglichkeit eine anonyme Funktion zu definieren ist der Einsatz das Schlüsselworts “function”. Auf die Unterschiede zu “fun” und den Einsatz werde ich aber erst kommen, nachdem wir das Thema “Pattern Matchning” durchgenommen haben.

Listen

Listen werden in F# mit Hilfe von eckigen Klammer definiert. Eine leere Liste wird beispielsweise einfach folgendermaßen dargestellt:

  1. let emptylist = []

Um Elemente am Anfang einer Liste anzuhängen werden 2 Doppelpunkte verwendet:

  1. let twoElementList = "1" :: "2" :: []

Wichtig hierbei ist, dass das letzte Element der Liste wiederum eine leere Liste ist! Es könnte sich dabei auch um ein Listenelement haneln (wie z.B. [”3″]). Wichtig sind die eckigen Klammern, welche klar signalisieren, dass es sich hier wirklich um eine Liste handelt!

  1. let twoElementList = "1" :: "2" // Fuehrt zu einem Fehler!

wäre z.B. keine F# konforme Liste!!
Zur reinen Definition von Listen ist diese Schreibweise evtl. ein wenig umständlich. Die gleiche Liste lässt sich auch mit Hilfe des Zeichens “;” so definieren:

  1. let twoElementList = ["1"; "2"]

Zur Konkatenierung von Listen bietet F# den Operator “@” an. Wichtig hierbei ist, dass F# nur erlaubt Listen gleichen Typs zu konkatenieren! Eine zulässige Konkatenierung von 2 Listen wäre also z.B. folgende:

  1. let concatList = ["1"; "2"] @ ["3"; "4"]

In F# sind Listen immutable, was heißt, dass eine erstellte Liste nicht nachträglich verändert werden kann! D.h. Operatoren, welche auf den Listen arbeiten verändern diese nicht sondern erstellen bei einer Änderung eine komlpett Neue:

  1. // Erstellen einer neuen Liste auf Basis einer Vorhandenen
  2. let FirstList = ["1"; "2"]
  3. let SecondList = "0" :: FirstList

Als letztes möchte ich euch noch zeigen, wie man mit Hilfe der “iter”-Funktion, der F#-Collection-Klasse “List” die Elemente einer Liste anzeigen kann. Die “iter”-Funktion erhält als Argumente eine Funktion und eine Liste. Sie wendet dann die übergebene Funktion auf jedes Element der Liste an (functional programming lässt grüßen :D)! Mit folgendem Konstrukt können wir also die Elemente der Liste FirstList ausgeben:

  1. // Normale Liste mit 2 Elementen
  2. let FirstList = ["1 "; "2"]
  3.  
  4. // Gibt alle Elemente der uebergebenen
  5. // String-Liste auf der Konsole aus
  6. let printListItems (list : List&lt;string&gt;)=
  7.     print_string "Elemente der Liste: "
  8.     // Anwenden der Funktion print_string
  9.     // auf jedes Elemenet von list
  10.     List.iter print_string list
  11.  
  12. // Aufrufen der Funktion printListItems
  13. printListItems(FirstList)

Die Klasse List ist eine generische Listenklasse der F#-Klassenbibliothek. Mit “(list : List<string>)” sagen wir, dass die übergebene Liste aus Elementen vom Typ “string” bestehen muss. (Diese Einschränkung machen wir, da wir bei “List.iter” die Funktion “print_string” übergeben.) Auf Klassen in F# kommen wir aber ein anderes mal zu sprechen.

Diesmal gibt es keine Aufgabe zum Lösen:-). Ihr könnte ja ein wenig mit Listen rumspielen, um ein besseres Gefühl dafür zu bekommen. Beim nächsten Teil folgt dann dafür eine etwas kniffligere Aufgabe;)…

  1. 3 Responses to “F#, Funktionale Programmierung mit .NET, Teil 3”

  2. Da es dieses mal keine Übung gibt, hab ich irb angeworfen und die Beispiele in Ruby ausprobiert, da hier auch sehr viele funktionale Aspekte in die Sprache iengeflossen sind. Die Syntax sieht verblüffent ähnlich aus.

    (Hoffentlich formatiert es den Code richtig. Die beiden Zeichen am Anfang ist immer der Prompt: > steht für Eingabe, = für Ausgabe und das ? für eine Eingabe über mehrere Zeilen.)

    >> ergebnis = lambda {|x, y| x*y }.call(2, 4)
    => 8
    >> list = [”1″, “2″] + [] + [”3″]
    => [”1″, “2″, “3″]
    >> printListItems = proc {|list| list.each {|i|
    ?> puts “Element der Liste: ” + i
    >> }}
    => #
    >> printListItems.call(list)
    Element der Liste: 1
    Element der Liste: 2
    Element der Liste: 3
    => [”1″, “2″, “3″]

    By Aaron on Feb 23, 2008

  3. Interessante Sasche!

    By Andreas on Feb 24, 2008

  1. 1 Trackback(s)

  2. Feb 24, 2008: technetbloggers.de » Blog Archive » C# like F#

Post a Comment