Передача аргументов функциям более высокого порядка

#scala

Вопрос:

как передать различные параметры для моей функции внутри функции более высокого порядка. мой код ниже.

 val sum = (a: Int, b:Int) => a   b
    
val x = 7
val y = 9
    
def sq (x: Int, y: Int, f: (Int, Int)=> Int): Int = {
  x   y * f(a,b)
}
    
println(sq(x,y,sum(2,3)))
 

Это не работает и выдает ошибку, которая 'a' is not defined .

Комментарии:

1. В чем смысл передачи функции , если метод , получающий ее, не знает, как ее вызвать, и, скорее, пользователь должен ее вызывать? Например, почему бы просто не попросить: def sq (x: Int, y: Int, z: Int): Int = x y z ?

2. a и b являются ли имена, которые будут использоваться внутри функции sum . Вы собираетесь передавать значения x , y как a , b ; следовательно x , и y будет иметь место a вызов функции и b в вызове функции. так что ваш sq будет x y * f(x, y) (если вы хотите квадрат, тогда (x y) * f(x, y) ), и вы позвоните sq как sq(x, y, sum) . На самом деле вам даже не нужно определять эти val x = 7 «и val y = 9 «. Вы можете напрямую использовать sq(7, 9, sum) .

3. Можете ли вы определить словами, что sq следует делать? Как его следует использовать f ?

4. Также обратите внимание, что вы смешиваете x и y как имена параметров метода, и как переменные, определенные вне метода, это сбивает с толку, чтобы понять, что вы действительно хотите сделать

Ответ №1:

Список параметров для sq выглядит нормально. Вызов sq неправильный, функция будет оценена до того, как она будет передана. Предполагая, что он был получен компилятором, чего, конечно, нет.

Передача функции не означает, что ее аргументы пригодятся для использования. Передача функции означает, что вызывающий может не знать, какие аргументы использовать или даже следует ли вызывать функцию. Функция sq должна предоставлять аргументы при ее вызове. а и в не означают ничего, кроме определения суммы. sq может предоставить x и y в качестве аргументов для суммирования.

Ответ №2:

Просто в качестве дополнения к ответу @Nathan. Этот пример имел бы смысл:

 val sum = (a: Int, b:Int) => a   b
   
    
def sq (x: Int, y: Int, f: (Int, Int)=> Int): Int = {
  x   y * f(x, y)
}

val x = 7
val y = 9
    
println(sq(x,y,sum))
 

Это будет оцениваться в вашей sg функции следующим образом:
7 9 * sum(7, 8)

Я надеюсь, что в этом есть смысл.

Ответ №3:

В дополнение к @Nathan Hughes ответу, если вы хотите передавать другой аргумент функции sum при каждом вызове, вам нужно изменить свой sq метод, например

 def sq (x: Int, y: Int, f: (Int, Int)=> Int): (Int, Int)=> Int = {
  x   y * f(_: Int, _:Int)
}
 

Вместо того, чтобы ожидать, что int из sq метода вернет частично примененную функцию типа (Int, Int) => Int из `sq’, затем передаст другой аргумент этой функции, например,

 sq(10, 20, sum)(1, 2) // 1st approach

//2nd approach would be
//You can hold the function in another variable and call that function with other arguments
val partialSum = sq(10,20, sum)
partialSum(1, 2)
 

и вы получите свой результат.

Или , если вы все еще хотите, чтобы этот sq метод возвращался Int , вы можете определить свой sq метод следующим образом

 def sq (x: Int, y: Int, f: (Int, Int)=> Int)(a:Int, b:Int):Int = {
   x   y * f(a, b)
}

scala> sq(10,20, sum)(1,2)
res2: Int = 70