2013-03-08 14 views
10

In Scala, warum kann eine Curry-Funktion einfach direkt an andere Funktionen übergeben werden, aber wenn es zu einer val zugewiesen wird, muss man es auch teilweise mit _ anwenden? Zum Beispiel die beiden Funktionen gegeben:Warum benötigt Scala die teilweise Anwendung von Curry-Funktionen bei der Zuweisung zu einem Wert?

test(5, curried(5)) 

und alles ist glücklich:

def curried(a: Int)(b: Int) = a + b 
def test(a: Int, f: Int => Int) = f(a) 

ich leicht curried-test mit passieren kann. Allerdings, wenn ich einfach curried(5) nenne ich eine Fehlermeldung erhalten:

scala> curried(5) 
<console>:9: error: missing arguments for method curried; 
follow this method with `_' if you want to treat it as a partially applied function 
       curried(5) 

Wenn ich den Anruf ändern jedoch Typinformationen enthalten, es funktioniert:

val 'curried: Int => Int = curried(5) 

jemand das rationale hinter der Inkonsistenz erklären kann, sicherlich die Scala-Compiler kann folgern, dass die Funktion Int => Int angesichts der Typdefinition der ursprünglichen Methode ist?

+0

Im 'val'-Fall, wenn Sie einen Typ Annotation geben, brauchen Sie die offene partielle Anwendung' _' nicht. –

Antwort

8

Das Problem schließt nicht den Typ, das Problem leitet Ihre Absicht ab. Haben Sie einen Fehler gemacht oder haben Sie absichtlich die Funktion curry?

Leider ist die Syntax des abschließenden Unterstrichs die formale Syntax, und das Weglassen ist syntaktischer Zucker.

+0

Das macht Sinn, aber die Tatsache, dass ich die Methode als Curry-Funktion deklarierte, hat meine Absicht schon beschrieben. Wenn das Problem in der Absicht liegt, warum ist es in Ordnung, inlining? –

+0

@MarkDerricutt Ich bin nicht sicher, was du mit "Inlining" meinst, aber in allen Fällen hast du gezeigt, wo es dich _declared_ erfüllt, was du erwartet hast, also geht Scala mit Currying weiter, weil es deinen Erwartungen entspricht. Was die erstere anbelangt, scaliert Scala nicht implizit, sie cursiviert explizit mit einem abschließenden Unterstrich oder wenn die Typen übereinstimmen - wenn Sie aus einer Sprache mit implizitem Currying kommen, die vielleicht unnatürlich erscheint. Die Funktion _declaration_ deklariert jedoch mehrere Parameterlisten, die für andere Dinge als das Curry nützlich sind. –

+0

Mit "Inlining" meinte ich die Verwendung in der Argumentposition (darüber nachzudenken, tho, die Zuordnung zum Argument hat vollqualifizierte Typinformationen, so ist im Wesentlichen das gleiche wie in meinem letzten Beispiel). Ich hatte Scala explizites Currrying angenommen, um von den Mehrfachargumentlisten zu kommen, anders als Haskells Methode, in der jede Methodendeklaration implizit curried ist und irgendein Anruf mit fehlenden Argumenten gerade die curried Funktion an dieser Position zurückbringt. Meine Verwirrung kommt von der Annahme, dass "mehrere Parameterlisten == currying", offensichtlich ist dies nicht speziell der Fall. –

0

Der Unterstrich wird nicht immer benötigt. Von http://docs.scala-lang.org/cheatsheets/

val zscore = (mean:R, sd:R) => (x:R) => (x-mean)/sd 

currying, offensichtliche Syntax.

def zscore(mean:R, sd:R) = (x:R) => (x-mean)/sd 

currying, offensichtlich Syntax

def zscore(mean:R, sd:R)(x:R) = (x-mean)/sd 

currying, Zucker-Syntax. aber dann:

val normer = zscore(7, 0.4) _ 

Notwendigkeit Hinterstrich die teilweise zu bekommen, nur für den Zucker Version.

Verwandte Themen