¿Cómo puedo entender este ejemplo de recursión en Scala?
Tengo el siguiente método en Scala que utiliza la recursión:
def foldLeft[Result](initial:Result, op:(Result, Elem) => Result) : Result = {
if (isEmpty)
initial
else
tail.foldLeft(op(initial,head), op)
Sin embargo, no entiendo cómo funciona la recursión en la última línea. Parece un poco convocado para mí porque el dobleizquierda se llama en la cola de una lista antes de que se haga otra cosa. ¿Cómo se ven los niveles de recursión aquí?
¿Puede alguien explicar cómo funciona esto exactamente?
Pregunta hecha hace 3 años, 4 meses, 29 días - Por binarybuilder
3 Respuestas:
-
No estoy seguro de lo que quieres decir con "el dobleizquierda se llama en la cola de una lista antes de que se haga otra cosa". Llamada
tail.foldLeft
es la última cosa hecha (en el caso de una lista no vacía.Scala (como la mayoría de los idiomas en uso amplio hoy) utiliza un estricto estrategia para evaluar una aplicación de la función (Haskell es probablemente el lenguaje más utilizado que utiliza una estrategia no restrictiva, y Scala es probablemente el lenguaje más utilizado que apoya directamente la exclusión de la estrategia estricta). Esto significa que cuando se aplica una función, los argumentos son completamente evaluados y luego pasan a la función.
Por lo tanto, es absolutamente correcto imaginar el compilador traduciendo el código en la pregunta al equivalente en Scala:
if (isEmpty) { initial } else { val _arg1 = op(initial, head) tail.foldLeft(_arg1, op) }
Por ejemplo
List(1, 2, 3, 4).foldLeft(0, _ + _)
evaluaría en (porque
List(1, 2, 3, 4)
no está vacía)List(2, 3, 4).foldLeft(1, _ + _)
y luego hacia (desde entonces)
List(2, 3, 4)
no está vacía)List(3, 4).foldLeft(3, _ + _)
y luego hacia (desde entonces)
List(3, 4)
no está vacía)List(4).foldLeft(6, _ + _)
y luego hacia (desde entonces)
List(4)
no es vacío; y suponiendo que usted está usandoNil
para representar la lista vacía)Nil.foldLeft(10, _ + _)
y luego hacia (desde entonces)
Nil
está vacía)10
Respondida el Dec 17, 2020 a las 00:26 - por bughunterx
Votos positivos: 0 | Votos negativos: 0 -
Claro, te puedo explicar cómo funciona la recursión en este ejemplo de Scala.
En el método
foldLeft
, se realiza una operación de plegado en una lista recursivamente. El método toma dos parámetros:initial
, que es el valor inicial del plegado, yop
, que es una función que define la operación a realizar en cada elemento de la lista.En la última línea
tail.foldLeft(op(initial,head), op)
, la recursión se lleva a cabo llamando al métodofoldLeft
en la cola de la lista (tail
). Lo que hace esta llamada es aplicar la operaciónop
al valor actual acumulado (initial
) y el siguiente elemento de la lista (head
), y luego pasar ese valor acumulado actualizado junto con la funciónop
a la llamada recursiva en la cola de la lista (tail
).En cada llamada recursiva, el valor acumulado se actualiza con el resultado de aplicar la operación
op
al valor actual y el siguiente elemento de la lista. Este proceso continúa hasta que la lista esté vacía, en cuyo caso se devuelve el valor acumulado final.En resumen, la recursión en este ejemplo se realiza de manera acumulativa, aplicando la operación definida por la función
op
en cada elemento de la lista y actualizando el valor acumulado en cada paso. La recursión termina cuando la lista está vacía y se devuelve el valor acumulado final.Respondida el Dec 18, 2020 a las 00:29 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
Cómo funciona la recursión en el ejemplo de Scala:
La función
foldLeft
implementa el pliegue por la izquierda para una lista, reduciendo iterativamente la lista de elementos a un único resultado.Explicación de la última línea:
scala tail.foldLeft(op(initial,head), op)
Esta línea invoca recursivamente
foldLeft
en la cola de la lista (el resto de la lista sin el elemento principal). Como argumento inicial, proporciona el resultado de aplicarop
alinitial
y alhead
de la lista actual.Niveles de recursión:
El método se llama inicialmente en la lista completa, con
initial
como argumento inicial. Para cada elemento en la lista, se llama recursivamente afoldLeft
en la cola de la lista. El argumento inicial para cada llamada recursiva es el resultado de aplicarop
al argumento inicial anterior y al elemento actual. La recursión continúa hasta que se alcanza el elemento final de la lista. En ese punto, el argumento inicial de la llamada final se devuelve como el resultado.Ejemplo:
Supongamos que tenemos la lista
List(1,2,3)
y queremos sumar todos sus elementos usandofoldLeft
:Inicialmente, se llama a
foldLeft
en toda la lista coninitial=0
. La primera llamada recursiva se realiza enList(2,3)
coninitial=1
. La segunda llamada recursiva se realiza enList(3)
coninitial=3
. La tercera llamada recursiva se realiza enList()
coninitial=6
. ComoList()
está vacía, se devuelveinitial=6
. Las llamadas recursivas anteriores devuelven este valor, resultando en un resultado final de6
.Conclusión:
La recursión en la última línea permite que
foldLeft
reduzca iterativamente la lista aplicando repetidamente la operación especificada (op
) a cada elemento y el argumento inicial acumulado. El proceso continúa hasta que se alcanza el elemento final y se devuelve el resultado acumulado.Respondida el Dec 18, 2020 a las 00:33 - por Gemini
Votos positivos: 0 | Votos negativos: 0