Verwendung nur f
statt ::f
, es ist bereits ein Funktionswert (das heißt ein Parameter, eine Variable oder eine Eigenschaft eines funktionellen Typs), so dass Sie nicht einen aufrufbare Bezug daraus machen müssen.
... else { it -> f(kleisli(n - 1, f)(it)) }
Auch scheint Ihr Beispiel eine Typenkonflikt zu haben: kleisli(n - 1, f)
eine Funktion vom Typ gibt (A) -> B
, die auf it
vom Typ A
, Rückkehr ein Ergebnis vom Typ B
genannt wird. Dann wird das Ergebnis an f
übergeben, aber f
kann nur A
empfangen. Um dies zu beheben, können Sie Typparameter B
und lassen Sie entfernen nur A
:
fun <A> kleisli(n: Int, f: (A) -> A) : (A) -> A =
if (n == 1)
f else
{ it -> f(kleisli(n - 1, f)(it)) }
(runnable demo of this code)
Auch dieser Code die Absicht sehr gut in funktionalen Stil zeigt, aber es könnte zur Folge haben, in Redundante Objektzuordnung und unerwünschtes Call-Stack-Wachstum. Es kann jedoch in einen imperativen Stil umgeschrieben werden, der effizienter arbeitet:
fun <T> iterativeKleisli(n: Int, f: (T) -> T) : (T) -> T = { x ->
var result = x
for (i in 1..n)
result = f(result)
result
}
Vielen Dank! Das funktioniert. Scheint so, als müsste ich viel mehr über Kotlin wissen. Und es tut mir leid, dass ich f fehlt, um f zu komponieren, denn f muss a-> a sein. –
Nur aus Neugier, was bedeutet dieser Fehler (Verweise auf Variablen werden noch nicht unterstützt)? –
@ Koyomi-chan, '' f' würde, wenn es unterstützt würde, eine aufrufbare Referenz auf den Parameter 'f' der Funktion bedeuten - ein Objekt, das einige Informationen über diesen Parameter enthält und eine Möglichkeit bietet, seinen Wert zu erhalten. Es gibt bereits [Funktionsreferenzen] (http://kotlinlang.org/docs/reference/reflection.html#function-references) und [bound callable references] (https://gist.github.com/udalov/f86fbea722a53730f3f5777d871ab8ba) in Kotlin, beide mit '::'. Lokale Variablen- und Parameterreferenzen werden jedoch vorerst nicht unterstützt. – hotkey