RDW #9 - Raetsel der Woche Nummer 9 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Regeln:  * Bitte nicht vor Ablauf der ersten 72 Stunden ( = drei Tage ) nach ~~~~~~~    Veroeffentlichung Hinweise (Spoiler) oder Loesungen veroeffent-            lichen!          * Wenn diese Zeit abgelaufen ist, werde ich einen Thread mit passen-            dem Titel erstellen, in dem die Loesungen gepostet werden und dis-            kutiert werden koennen.          * Die Loesungen sollten nicht nur gepostet, sondern auch an mich ge-            mailt werden, damit ich sie testen, "bewerten"  und zusammenfassen            kann. Die Adrese dafuer lautet:            crian <---AT---> perl <---MINUS---> community <---DOT---> de            Im Betreff sollte 'RDW' und die Nummer des Raetsels stehen. Hilf-            reich waere neben dem Quellcode der Username im Forum sowie Perl-            und OS-Version, falls Du diese kennst.          * Verstaendnisfragen duerfen in diesem Thread gestellt werden, aber            Tipps und (Teil-) Loesungen sind hier unerwuenscht.          * Ich werde die eingeschickten Programme im Netz zur Verfuegung            stellen, so dass gerade lange Quellcodes nicht (komplett)            gepostet werden muessen.          * Zur Verwendung von Modulen: Ich moechte diese nicht generell aus-            schliessen, aber wenn quasi die komplette Aufgabe durch die Ver-            wendung eines Moduls ersetzt werden kann, ist dies vielleicht nicht            der Sinn der Aufgabe gewesen. Aufgabe: Funktionen einstellig machen ~~~~~~~~          (Dieser Vorschlag stammt von Kabel, Fragen bitte an ihn richten =)          Es reicht aus, wenn man nur Funktionen erlaubt, die ein Argument be-          kommen. D.h. man benoetigt keine mehrstelligen Funktionen.          Beispiel 1: Die zweistellige Funktion add              sub add { $_[0] + $_[1] }          kann auch so geschrieben werden              sub add {                  my $arg1 = shift;                  return sub {                      my $arg2 = shift;                      return $arg1 + $arg2                  };              }          dadurch veraendert sich der Aufruf:              vorher:     print add(1, 2);      # "3"              nachher:    print add(1)->(2);    # "3"          Der Vorgang des Verminderns der Stelligkeit einer Funktion heisst          "currying".          Aufgabe: Schreibe eine Funktion curry(), deren erster Parameter die          zu "curriende" Funktion ist, deren zweiter Parameter die Stelligkeit          dieser Funktion, und die die obige Transformation ausfuehrt.          Beispiel 2: builtin print              my $myprint = sub { print @_; };     # "referenz auf print"              my $myprint_transformed = curry ($myprint, 3);              $myprint_transformed->(1);        # nix passiert              $myprint_transformed->(1)->(2);        # immer noch nix              $myprint_transformed->(1)->(2)->(3);    # "123"          Beispiel 3:              my $myadd = sub { return $_[0] + $_[1]; };              my $myadd_transformed = curry ($myadd, 2);              my $add_three = $myadd_transformed->(3);              print $add_three (100); # "103"          Tipps:                        - Mache Dir klar, warum in Beispiel 2 die ersten beiden Aufrufe                von $myprint_transformed nichts bewirken.              - Von welcher Eigenschaft macht Beispiel 1 gebrauch?              - Darfst Du davon auch Gebrauch machen? Vergiss nicht, dass                curry() mit beliebigen Funktionen funktionieren soll!                    FRAGEN AUSDRUEKLICH ERWUENSCHT!          Kabel hat schon eine (weniger relevante) Luecke in der Spezifikation          gefunden. Er verraet aber nicht, wo (und befuerchtet, es sind noch          mehr drin.)          Kabel sagt: Die Loesung ist im Vergleich zur Aufgabenstellung fast          schon banal einfach;) Trotzdem wuerde ich die Aufgabe eher Richtung          schwer einschaetzen, denn hier wird heftigst von Closures Gebrauch          gemacht, und des ist nicht jedermanns Sache.