Scala: Wie definiert man eine Funktion, deren Eingabe (f, args) ist und deren Ausgabe f (args) ist?

8

Wie können Sie eine Funktion myEval(f, args) in Scala definieren, die als Eingabe eine andere Funktion f und Argumente args verwendet und deren Ausgabe f(args) ?

ist

Ich möchte nicht, dass myEval irgendwelche Vorkenntnisse über die Arity- oder Argumenttypen von f hat.

Warum ist das nützlich? Dies ist eine Möglichkeit, das Problem der Implementierung einer generischen Methode timeMyFunction(f, args) zu lösen. Wenn es einen Weg gibt, dies durch irgendeine Art von Lazy Val-Konstruktion zu tun, wäre das auch interessant.

Bearbeiten : Der bessere Weg zur Implementierung einer Timing-Methode wird in diese Frage . Durch Aufrufen von timeMyFunction( { f(args) } ) wird der Funktionsaufruf in eine anonyme Funktion Unit => Unit eingeschlossen. Also muss timeMyFunction nur 0-arity-Funktionen übernehmen.

Edit 2 : Sehen Sie Dirks Antwort für einen vielleicht effizienteren Weg, der eine anonyme Funktion vermeidet, indem Sie f als Referenz übergeben.

Also ist meine Rechtfertigung für die Frage jetzt nur meine Scala-Ausbildung.

    
expz 15.04.2014, 09:52
quelle

2 Antworten

9

Die Scala-Standardbibliothek wird Ihnen in den meisten Fällen nicht dabei helfen, Überartigkeiten zu verallgemeinern, aber Formlos ist dafür perfekt geeignet. So können Sie Ihre Funktion in Shapeless 1.2.4 schreiben:

%Vor%

Und dann:

%Vor%

Es sieht kompliziert aus, aber im Wesentlichen sagen Sie nur, dass Sie Beweise benötigen, dass eine Funktion f einer beliebigen Arbitrarität in eine Funktion mit einem Argument aus einer heterogenen Liste A in das Ergebnis R umgewandelt werden kann. und dass das Tupel P in eine heterogene Liste desselben Typs konvertiert werden kann.

    
Travis Brown 15.04.2014, 10:57
quelle
1

Eine Alternative zur Verwendung von Pass-by-Name wäre:

%Vor%

Obwohl dies so aussieht, als würde es someFunction direkt aufrufen, tut es das nicht, da timeIt das Argument "nach Namen" nimmt, dh der scala Compiler generiert eine versteckte Schließung, die den Aufruf ausführt, wenn der tatsächliche Wert wird in timeIt selbst benötigt.

Diese Variante kann aufgrund des Overheads der "pass-by-name" -Konvention ein gewisses Timing-Rauschen verursachen.

    
Dirk 15.04.2014 11:47
quelle

Tags und Links