Ich versuche Scala mit SICP zu lernen, aber ich habe eine harte Zeit mit Typdefinitionen von Funktionen und blieb bei SICP stecken. Hier eine verallgemeinerte Ausdruck bauen die Quadratwurzel einer Zahl zu finden (durch Festpunktsuche oder Newton-Verfahren), wo statt:Arten von Parametern in Funktionen, die Funktionen annehmen
def sqrt_damp(x: Double) =
fixed_point(average_damp(y => x/y))(1)
def sqrt_newton(x: Double) =
fixed_point(newton_method(y => square(y) - x))(1)
Basierend auf den Funktionen:
def square(x: Double) = x * x
def average(x: Double, y: Double) = (x + y)/2
def abs(x: Double) = if (x < 0) -x else x
val tolerance = 0.00001
def fixed_point(f: Double => Double)(first_guess: Double) = {
def close_enough(v1: Double, v2: Double): Boolean = abs(v1 - v2) < tolerance
def attempt(guess: Double): Double = {
val next = f(guess)
if (close_enough(guess, next)) next else attempt(next)
}
attempt(first_guess)
}
def average_damp(f: Double => Double): Double => Double =
x => average(x, f(x))
val dx = 0.00001
def deriv(g: Double => Double): Double => Double =
x => (g(x + dx) - g(x))/dx
def newton_transform(g: Double => Double): Double => Double =
x => x - g(x)/deriv(g)(x)
def newton_method(g: Double => Double)(guess: Double): Double =
fixed_point(newton_transform(g))(guess)
Die quadratischen Funktionen kann in Form verallgemeinern:
:(define (fixed-point-of-transform g transform guess)
(fixed-point (transform g) guess))
Was ich in Scala wie folgt versucht auszudrücken
def fixed_point_of_transform(g: Double => Double, transform: Double => Double)(guess: Double): Double =
fixed_point(transform(g))(guess)
Doch die oben nicht kompiliert und generiert die Fehler
type mismatch; found : Double => Double required: Double
bearbeiten, folgende Arbeiten:
def fixed_point_of_transform(g: Double => Double, transform: (Double => Double) => (Double => Double))(guess: Double): Double =
fixed_point(transform(g))(guess)
So, jetzt die bisherigen Funktionen können wie folgt definiert werden:
def sqrt_damp(x: Double) =
fixed_point_of_transform(y => x/y, average_damp)(1)
def sqrt_newton(x: Double) =
fixed_point_of_transform(y => square(y) - x, newton_method)(1)
Ich denke, ich habe es jetzt danke, also sollte ich 'transform: (Double => Double) => (Double => Double)' stattdessen – nzn