2017-06-14 5 views
0

Sorry wegen dieses Durcheinander. Ich komme immer noch meinen Weg in Scala. dies ist Umformulierung die alle Frage:Scala Pass-Funktion als Parameter für eine andere Funktion

def func1(x: Double, y: Double) = { 
    x+y 
} 

def func2(x: Double, y: Double) = { 
    x-y 
} 

def calc(f: (Double, Double) => Double, z: Int) = { 
    f(1,2) + z 
} 

//Sometimes I want to call 
calc(func1(1,2), 3) 

//Other times 
calc(func2(1,2), 3) 

und ich bekomme diese Fehlermeldung:

<console>:52: error: type mismatch; 
found : Double 
required: (Double, Double) => Double 
       calc(func1(1,2), 3) 
         ^

was ist der richtige Weg, Calc() aufzurufen?

dank

+0

Dies gibt keine Funktion als Parameter weiter, sondern gibt das Ergebnis einer Funktion weiter. –

+0

ja, du hast Recht – MLeiria

Antwort

0

allererst Sie eine var verwenden (wollen Detail gehen nicht in lesen this für weitere Informationen), die nicht eine gute Praxis betrachtet wird, wird, wenn Ihre Karte verwendet werden soll bedeuten, Innerhalb der Klasse können Sie eine änderbare Map erstellen.

zurück zu Ihrer Frage kommen: Wenn Sie Ihre Funktion wie erwartet funktioniert, dann sollten Sie sicherstellen, dass doSomeComputation Funktion, um die Werte zurückgibt, die von otherFunction als Eingang param, so etwas wie diese

erwartet wird
def doSomeComputation(m1: Map[String, List[(String, Double)]], name: String) = { 
     (Map("some_key" -> List(("tuple1",1.0))), "tuple2") 
} 

Rückgabetyp ist (Map [String, List [String, Int]], String)

aber es nicht viel Sinn für macht, was Sie wollen versuchen zu tun, kann ich Ihnen helfen zu verstehen, wenn Sie klar erwähnen können, was Sie erreichen wollen.

1

Beachten Sie, dass die Argumente zu f(), d. H. Die 1 und die , im Körper von calc() geliefert werden.

def calc(f: (Double, Double) => Double, z: Int) = { 
    f(1,2) + z 
} 

Deshalb brauchen Sie keine Argumente für die Funktionen angeben, in weitergegeben werden.

calc(func1, 3) 
calc(func2, 3) 
0

Sie finden die Funktion Signatur f: (Map[String,List[(String, Double)]], String) => Double und nicht nur den Rückgabetyp übergeben müssen. Ein trivialisiert Beispiel unten:

var testMap: Map[String, List[(String, Double)]] = Map(
    "First" -> List(("a", 1.0), ("b", 2.0)), 
    "Second" -> List(("c", 3.0), ("d", 4.0)) 
) 
// testMap: Map[String,List[(String, Double)]] = Map(First -> List((a,1.0), (b,2.0)), Second -> List((c,3.0), (d,4.0))) 

def doSomeComputation(m1: Map[String, List[(String, Double)]], name: String): Double = { 
    m1.getOrElse(name, List[(String, Double)]()).map(x => x._2).max 
} 
// doSomeComputation: (m1: Map[String,List[(String, Double)]], name: String)Double 

def doSomeOtherComputation(m1: Map[String, List[(String, Double)]], name: String): Double = { 
    m1.getOrElse(name, List[(String, Double)]()).map(x => x._2).min 
} 
// doSomeOtherComputation: (m1: Map[String,List[(String, Double)]], name: String)Double 

def otherFunction(f: (Map[String, List[(String, Double)]], String) => Double, otherName: String) = { 
    f(testMap, "First") * otherName.length 
} 
// otherFunction: (f: (Map[String,List[(String, Double)]], String) => Double, otherName: String)Double 

println(otherFunction(doSomeComputation, "computeOne")) 
// 20.0 

println(otherFunction(doSomeOtherComputation, "computeOne")) 
// 10.0 

auf Ihrem Anwendungsfall abhängig, könnte es eine gute Idee, auch otherFunctiontestMap und name als Parameter zu übergeben.

Verwandte Themen