Функция Curry в scala

#scala

#scala

Вопрос:

 object answer {
    def product(f:Int=>Int)(a:Int,b:Int):Int =
        if (a>b) 1
        else f(a) * product(f)(a 1,b)   
    product(x=>x*x)(3,4)
    def fact(n:Int) = product(x=>x)(1,n)
}
  

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

     // 3*3* product(f)(4,4)
    // 3*3 * (4*4) * product(f)(5,4)
    // 3*3 * 4*4 * 1
    // 3*3 * 4*4
    // 144
  

Однако я не понимаю этот блок кода
product(f)(a 1,b) кто-нибудь может объяснить мне насчет этой строки?

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

1. Чего ты не понимаешь? product является рекурсивной функцией

2. как вывести (f) эту строку?

3. Scala позволяет передавать функции в качестве аргументов, поэтому f определяется как функция, которая принимает Int и возвращает Int . Вы можете увидеть пример ее реализации: product(x=>x*x)(3,4) . В этом случае функция просто умножает Int то, что было передано. Внутри продукта значение a (равное 3) передается функции в else блоке f(a)

4. docs.scala-lang.org/tutorials/tour/higher-order-functions.html

Ответ №1:

Блок кода product(f)(a 1,b) представляет собой вызов метода product с аргументами: f , a 1 и b .

Подробнее:

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

  • Она рекурсивна, поскольку в ее теле есть вызов самой себя.
  • Она более высокого порядка, поскольку принимает функцию в качестве аргумента (см. Функции более высокого порядка).
  • Она имеет два списка параметров (см. currying):
    • первая функция состоит из одного параметра: функции f:Int=>Int ;
    • вторая содержит два параметра: a: Int и b: Int .

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

1. но у f должен быть один параметр Int f:Int=>Int , верно? и почему в product(f) нет какого-либо параметра для f , могло бы помочь прояснить . Спасибо

2. f сама по себе является параметром типа Int=>Int и ее можно передать другим функциям таким же образом, как и любую другую. Первый аргумент функции product должен иметь тип, Int=>Int чтобы f иметь соответствующий тип.

3. извините, просто непонятно, и поэтому f (a) в данном случае a является параметром f и a типа Int , возможно ли сделать подобное product(f(a))(a 1,b) ?

4. Нет, она не будет компилироваться, поскольку f(other) будет иметь тип Int (помните, что f это функция от Int to Int ), но product требует аргумента типа Int => Int .

Ответ №2:

product является рекурсивной функцией. Давайте немного проанализируем ее.

 def product(f:Int => Int)(a: Int, b: Int): Int
  

product принимает значение f , которое в данном случае является функцией от Int to Int . Кроме того, он принимает a и b , которые оба являются целыми числами. В случае этой функции, a и b будет интервалом, к которому будет применена product функция.

Теперь та часть, где вы не понимаете, заключается в следующем: product(f)(a 1, b) правильно. По сути, то, что она делает, заключается в том, что после того, как вы применили f к a , вам нужно применить f к остальным значениям в вашем интервале. То есть, поскольку a это сделано, вам нужно вычислить, начиная со следующего целочисленного значения, которое является a 1 .

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

1. и что (f) означает? а (a 1, a) является параметром f или параметром продукта?

2. (a 1, b) — параметр продукта, в котором (f) можно использовать. f существует функция, которая берется в качестве параметра product

Ответ №3:

Прежде всего, давайте разберемся, что такое функция curry. В общем случае функция curry имеет два параметра функции в двух скобках. Когда мы указываем параметр, функция возвращает другую функцию только с одним параметром. например:

 def sumInt1(a: Int)(b: Int): Int = {a   b}
def sumInt2(c: Int): Int = sumInt1(3)(c)
val test = sumInt2(5)  // test: 8
  

И, product(f)(a 1,b) единственное отличие от приведенного выше примера заключается в том, что f это функция, и функцию также можно рассматривать как параметр в scala.