Übergeben Sie einen Operator wie eine Funktion

Oct 13 2020

Während ich Raku lerne, komme ich zum Punkt der Funktion höherer Ordnung und der Sortierfunktion.

Ich habe dieses Beispiel:

> sort <4 6 2 9 1 5 11>
(1 2 4 5 6 9 11)

Dann sagt der Arzt für die Routine Folgendes:

Sorts the list, smallest element first. By default infix:<cmp>  is used for
comparing list elements.

Und das Buch, dem ich "Piensa en raku" in Abschnitt 9.2 folge , macht einen Vergleich zwischen numerischer und lexikografischer Sortierung.

Ich habe folgendes versucht:

> sort &le, <4 6 2 9 1 5 11>;
===SORRY!=== Error while compiling:
Undeclared routine:
    le used at line 1. Did you mean 'lc'?

Aber dieses Problem bekommen, anstatt die sortierte Liste lexikographisch geordnet. Vielleicht ist es zu früh für mich, dies zu verstehen, aber es sollte möglich sein, einen Operator in Raku wie eine Funktion zu übergeben, da auch in der Dokumentation angegeben ist, dass ein Infix verwendet wird: oder ich muss so etwas tun, vielleicht ich ' m verwirrende Operatoren und Unterprogramme:

sub my-le($a,$b) {
    $a le $b;
}

sort &my-le, <4 6 2 9 1 5 11>;

oder dieses:

   sort { $^b le $^a  }, <4 6 2 9 1 5 11>;

Ich habe also die Frage nach der unterschiedlichen Verwendung des Infix-Operators und einer Unterroutine. Vielleicht besteht das Problem bei diesem Unterschied darin, dass die Reihenfolge der Operanden das Ergebnis einiger Operationen beeinflusst. Sie können es also nicht so leicht als Funktion, Parameter oder Variable übergeben

> sort { $^a le $^b  }, <4 6 2 9 1 5 11>
(9 6 5 4 2 11 1)
> sort { $^b le $^a  }, <4 6 2 9 1 5 11>
(1 11 2 4 5 6 9)

Ich hoffe, dass ich meine Zweifel an diesem Problem erklären kann.

Antworten

19 ScimonProctor Oct 13 2020 at 16:59

Der leOperator ist ungefähr so ​​definiert:

sub infix:<le> { ... }

Das infix:Präfix teilt der Sprache mit, dass es sich um einen Infix-Operator handelt. Also, wenn Sie anrufen möchten, ist als Sub sein &infix:<le>(1,2)oder für Ihre Sorte:

sort &infix:<le>, <4 6 2 9 1 5 11>;
(9 6 5 4 2 11 1)

Dies kann helfen https://docs.raku.org/language/optut

12 jakar Oct 13 2020 at 17:12

Wenn Sie die Antwort von Scimon ergänzen und eine "klarere" Darstellung wünschen, können Sie das folgende Konstrukt verwenden:

sort *le*, <4 6 2 9 1 5 11>;

Der vorherige Code ist ein beliebiges Konstrukt (Codeobjekt).

Das beliebige Konstrukt verwendet mehrere *, um Codeblöcke (anonyme Unterprogramme) mit möglichst vielen Argumenten zu generieren:

my $c = * + *; # same as -> $a, $b { $a + $b }

Dies bedeutet, dass das Vorzeichen (*) verwendet wird, um die zwei (oder mehr) Parameter zu bezeichnen, die bei der Berechnung verwendet werden

Gleiches gilt für unseren Fall:

sort *le*, <4 6 2 9 1 5 11>;

ist das gleiche wie :

sort * le *, <4 6 2 9 1 5 11>;   # adding space between operator and the whatever sign (*)

und dies ist wiederum das gleiche wie:

sort -> $a, $b { $a le $b }, <4 6 2 9 1 5 11>;   # anonymous subroutine
 

oder

sort { $^a le $^b }, <4 6 2 9 1 5 11>;

oder auch

sub le {
    $^a le $^b
}

sort &le, <4 6 2 9 1 5 11>;

Verweise:

https://docs.raku.org/type/Whatever

https://docs.raku.org/type/Block