Типы параметров в функциях, которые принимают функции

Я пытаюсь изучить Scala с помощью SICP, но у меня проблемы с определениями типов функций, и я застрял на SICP. Здесь построено обобщенное выражение для нахождения квадратного корня числа (через поиск с фиксированной точкой или метод Ньютона), где вместо:

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)

В зависимости от функций:

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)

Квадратные функции можно обобщить в виде:

(define (fixed-point-of-transform g transform guess)
  (fixed-point (transform g) guess))

Что я попытался выразить следующим образом на Scala:

 def fixed_point_of_transform(g: Double => Double, transform: Double => Double)(guess: Double): Double =
   fixed_point(transform(g))(guess)

Тем не менее, вышеприведенное не компилируется и генерирует ошибку

type mismatch; found : Double => Double required: Double

Изменить, следующие работы:

def fixed_point_of_transform(g: Double => Double, transform: (Double => Double) => (Double => Double))(guess: Double): Double =
  fixed_point(transform(g))(guess)

Итак, теперь предыдущие функции можно определить как:

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)

person nzn    schedule 10.11.2016    source источник


Ответы (1)


transform принимает Double и возвращает Double. Вы не можете применить его к g, потому что g является функцией Double => Double. Вы можете применить его к g(x), где x: Double. Я думаю, это то, что вы хотите: fixed_point((x: Double) => transform(g(x)))(guess)

person radumanolescu    schedule 10.11.2016
comment
Я думаю, теперь я понял, спасибо, поэтому я должен вместо этого сделать transform: (Double => Double) => (Double => Double) - person nzn; 10.11.2016