He aprendido la diferencia básica entre foldLeftyreduceLeft
foldLeft:
- se debe pasar el valor inicial
reducir Izquierda:
- toma el primer elemento de la colección como valor inicial
- lanza una excepción si la colección está vacía
¿Hay alguna otra diferencia?
¿Alguna razón específica para tener dos métodos con una funcionalidad similar?
scala
functional-programming
fold
higher-order-functions
Rajesh Pitty
fuente
fuente

Respuestas:
Pocas cosas para mencionar aquí, antes de dar la respuesta real:
left, se trata más bien de la diferencia entre reducir y plegarDe vuelta a su pregunta:
Aquí está la firma de
foldLeft(también podría haber sidofoldRightpara el punto que voy a hacer):Y aquí está la firma de
reduceLeft(de nuevo, la dirección no importa aquí)Estos dos se ven muy similares y por lo tanto causaron la confusión.
reduceLeftes un caso especial defoldLeft(que por cierto significa que a veces puedes expresar lo mismo usando cualquiera de ellos).Cuando llame a
reduceLeftsay en unList[Int], literalmente reducirá toda la lista de enteros en un solo valor, que será de tipoInt(o un supertipo deInt, por lo tanto[B >: A]).Cuando llame a
foldLeftsay en unList[Int], plegará toda la lista (imagine rodar un trozo de papel) en un solo valor, pero este valor no tiene que estar relacionadoInt(por lo tanto[B]).Aquí hay un ejemplo:
Este método toma un
List[Int]y devuelve unTuple2[List[Int], Int]o(List[Int], Int). Calcula la suma y devuelve una tupla con una lista de enteros y es la suma. Por cierto, la lista se devuelve hacia atrás, porque usamos enfoldLeftlugar defoldRight.Mira One Fold para gobernarlos a todos y obtener una explicación más detallada.
fuente
Bes un supertipo deA? PareceBque en realidad debería ser un subtipo deA, no un supertipo. Por ejemplo, suponiendo queBanana <: Fruit <: Foodsi tuviéramos una lista deFruits, parece que puede contener algunosBananas, pero si contuviera algunoFood, el tipo seríaFood, ¿correcto? Así pues, en este caso, siBes un subtipo de élAy hay una lista que contiene ambosBs yAs, la lista debe ser de tipoB, noA. ¿Puedes explicar esta discrepancia?List[Banana]puede reducirse a un soloBananao un soloFruito un soloFood. PorqueFruit :> Bananay 'Comida:> Plátano'.Bananapuede contener unFruit", lo que no tiene sentido. Su explicación tiene sentido: laffunción que se pasareduce()puede dar como resultado aFruito aFood, lo que significa queBla firma debe ser una superclase, no una subclase.reduceLeftEs solo un método de conveniencia. Es equivalente afuente
reducelftembargofoldfunciona en una lista vacía, mientrasreduceque no.foldLeftes más genérico, puede usarlo para producir algo completamente diferente de lo que introdujo originalmente. MientrasreduceLeftque solo puede producir un resultado final del mismo tipo o supertipo del tipo de colección. Por ejemplo:El
foldLeftva a aplicar el cierre con el último resultado plegada (por primera vez usando el valor inicial) y el siguiente valor.reduceLeftpor otro lado, primero combinará dos valores de la lista y los aplicará al cierre. A continuación, combinará el resto de los valores con el resultado acumulativo. Ver:Si la lista está vacía,
foldLeftpuede presentar el valor inicial como un resultado legal.reduceLeftpor otro lado, no tiene un valor legal si no puede encontrar al menos un valor en la lista.fuente
La razón básica por la que ambos están en la biblioteca estándar de Scala es probablemente porque ambos están en la biblioteca estándar de Haskell (llamada
foldlyfoldl1). SireduceLeftno fuera así, a menudo se definiría como un método de conveniencia en diferentes proyectos.fuente
Como referencia, se
reduceLeftproducirá un error si se aplica a un contenedor vacío con el siguiente error.Reelaborando el código para usar
Es una opción potencial. Otra es usar la
reduceLeftOptionvariante que devuelve un resultado envuelto en Opción.fuente
De los principios de programación funcional en Scala (Martin Odersky):
[a diferencia de
reduceLeft, lo que arroja una excepción cuando se invoca en una lista vacía.]El curso (ver lección 5.5) proporciona definiciones abstractas de estas funciones, que ilustran sus diferencias, aunque son muy similares en su uso de la coincidencia de patrones y la recursividad.
Tenga en cuenta que
foldLeftdevuelve un valor de tipoU, que no es necesariamente el mismo tipo queList[T], pero reduceLeft devuelve un valor del mismo tipo que la lista).fuente
Para comprender realmente lo que está haciendo con fold / reduce, consulte esto: http://wiki.tcl.tk/17983 muy buena explicación. una vez que obtenga el concepto de doblar, reducir aparecerá junto con la respuesta anterior: list.tail.foldLeft (list.head) (_)
fuente