C# like F#

24. Februar 2008 – 17:49 von Andreas

In meinem vorherigen Post (F# Teil 3) habe ich unter anderem die Methode “iter” der F#-Klasse List verwendet. Darauf hatte Aaron als Kommentar auf meinen Eintrag folgende ähnliche Lösung in Ruby gepostet:

Code von Aaron:

>> 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″]

Zur Erinnerung: Die “iter”-Funktion erhält als Argumente eine Funktion und eine Liste. Sie wendet dann die übergebene Funktion auf jedes Element der Liste an. Warum die C#-Listen-Klasse nicht um die F#-”iter”-Funktion erweitern (als Extension Method). Genau dies habe ich nun getan! Den Code hierzu (und einen kleinen Testaufruf) möchte ich euch nicht vorenthalten:):

  1. public static class ExtensionMethods
  2.     {
  3.         /// <summary>
  4.         /// Funktionszeiger fuer eine generische
  5.         /// Funtkion mit einem Parameter und keinem
  6.         /// Rueckgabewert.
  7.         /// </summary>
  8.         /// <typeparam name="T">Typ des Parameters.</typeparam>
  9.         /// <param name="arg0">Parameter der Funktion.</param>
  10.         public delegate void Func<T>(T arg0);
  11.  
  12.         /// <summary>
  13.         /// Die iter-Funktion erhaelt als Argumente eine Funktion
  14.         /// und eine Liste. Sie wendet dann die uebergebene Funktion
  15.         /// auf jedes Element der Liste an.
  16.         /// </summary>
  17.         /// <typeparam name="T">Typ der Elemente, der Liste.</typeparam>
  18.         /// <param name="l">Extension-Method auf die C#-List-Class.</param>
  19.         /// <param name="func">Die Funktion, welche auf die Listenelemente
  20.         /// angewendet werden soll.</param>
  21.         public static void iter<T>(this List<T> l, Func<T> func)
  22.         {
  23.             // Ueber die Elemente der Liste iterieren
  24.             l.ForEach((T element) =>
  25.             {  
  26.                 // Die Funktion auf das jeweilige Element anwenden.
  27.                 func(element);
  28.             });
  29.         }
  30.     }
  31.  
  32.     class Program
  33.     {  
  34.  
  35.         static void Main(string[] args)
  36.         {
  37.             // Neue string-Liste erstellen
  38.             var list = new List<string>() { "Andi ", "Maier" };
  39.             // Verwendung der iter-Funktion:
  40.             // Die Funktion "Console.Write" auf die string-
  41.             // Elemente anwenden.
  42.             list.iter<string>(Console.Write);
  43.  
  44.             Console.ReadLine();
  45.         }
  46.     }
  1. 8 Responses to “C# like F#”

  2. Also das kann ich auch ;-)

    # Funktion:
    itr() {
    for ELEMENT in `echo $1`; do
    $2 $ELEMENT
    done
    }

    # Testen:
    $ LIST=”eins zwei drei vier fuenf”
    $ itr $LIST echo
    eins
    zwei
    drei
    vier
    fuenf

    Das war Bash :D
    Zur Info: $ steht immer für den Prompt bei der Eingabe auf der Shell

    By nougad on Feb 24, 2008

  3. NACHTRAG: OK, das Bash Beispiel hatte wenig mit Funktionaler Programmierung zu tun. Deshalb hier noch ein Beispiel:

    printListItems = function(list) {
    document.writeln(list.shift());
    if (list.length > 0) self.printListItems(list);
    }
    printListItems([”eins”, “zwei”, “drei”]);

    By nougad on Feb 24, 2008

  4. Das sieht stark nach JavaScript aus, das letzte Beispiel. In Bash wird es denke ich sehr schwer werden eine Art “iter”-Funktion zu implementieren, weil man einfach keine Blocks/Func-Objekte/Anonyme Funktionen als Parameter übergeben kann.

    Interessant wäre es jetzt mal auszutesten ob man das mit reinem C (welches KEINE Blocks kennt) hinbekommen könnte (über einen Zeiger der auf eine Funktion zeigt vielleicht?)

    By Aaron on Feb 24, 2008

  5. Nicht ganz so schön dynamisch wie in Ruby aber geht :D

    #include

    void multiply(int x) {
    printf(”%i * 10 = %i\n”, x, x*10);
    }

    void iteri(int *list, void (*func)(int)) {
    int i;
    for (i=0; i<=sizeof(list); i++) {
    (*func)(list[i]);
    }
    }

    int main() {
    int list[] = {1, 2, 3, 4, 5};
    iteri(list, multiply);

    return 0;
    }

    By Aaron on Feb 24, 2008

  6. Dieses Kommentarteil zensiert alle spitzen Klammern (< und >) sonst würde da auch JS stehen ;-)

    Und bei dir fehlt die Include Anweißung. ANDREAS mach mal wieder hin :D

    By nougad on Feb 24, 2008

  7. Das Bsp. mit C fand ich ja mal cool! Den Zeiger auf Funktionen in C kannte ich bis grad auch noch nicht! Aber cool zu wissen:)! Was aber als Sprache ganz klar noch fehlt ist…. naa was wohl? Die Mutter aller Sprachen! Genau: A001101embler:D…

    By Andreas on Feb 24, 2008

  8. Hmm, stattdessen könnte man ja auch einfach ForEach benutzen…!?

    var list = new List() { “sadf”, “lkjsh”, “sreli” };

    list.ForEach( Console.WriteLine );

    ;)

    By Icke on Feb 25, 2008

  9. Manchmal sieht man den Wald vor lauter Bäumen nicht :D. Du hast natürlich Recht! Prinzipiell ist meine “iter”-Funktion nur ein geschachtelter Aufruf der neuen ForEach-Funktion :).

    By Andreas on Feb 25, 2008

Post a Comment