Разница между складками и foldLeft или foldRight?

ПРИМЕЧАНИЕ. Я нахожусь на Scala 2.8. Может это проблема?

Почему я не могу использовать функцию fold же, как foldLeft или foldLeft ?

В Set scaladoc говорится, что:

Результатом сгибания может быть только супертип параметра T параллельной коллекции.

Но я не вижу параметра типа T в сигнатуре функции:

 def fold [A1 >: A] (z: A1)(op: (A1, A1) ⇒ A1): A1 

В чем разница между foldLeft-Right и fold , и как использовать последнюю?

РЕДАКТИРОВАТЬ: Например, как бы я написал сводку, чтобы добавить все элементы в список? С foldLeft это будет:

 val foo = List(1, 2, 3) foo.foldLeft(0)(_ + _) // now try fold: foo.fold(0)(_ + _) >:7: error: value fold is not a member of List[Int] foo.fold(0)(_ + _) ^ 

Вы правы в том, что старая версия Scala является проблемой. Если вы посмотрите на страницу scaladoc для Scala 2.8.1, вы увидите, что там не определено фолд (что соответствует вашему сообщению об ошибке). Видимо, fold был введен в Scala 2.9.

Короткий ответ:

foldRight ассоциируется справа. Т.е. элементы будут накапливаться в порядке справа налево:

 List(a,b,c).foldRight(z)(f) = f(a, f(b, f(c, z))) 

foldLeft ассоциируется слева. Т.е. аккумулятор будет инициализирован, и элементы будут добавлены к аккумулятору в порядке слева направо:

 List(a,b,c).foldLeft(z)(f) = f(f(f(z, a), b), c) 

fold ассоциативен тем, что порядок, в котором элементы складываются вместе, не определен. То есть аргументы fold образуют monoид .

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

Для вашего конкретного примера вы будете кодировать его так же, как и с foldLeft.

 val ns = List(1, 2, 3, 4) val s0 = ns.foldLeft (0) (_+_) //10 val s1 = ns.fold (0) (_+_) //10 assert(s0 == s1) 

Согласитесь с другими ответами. подумал о том, чтобы дать простой иллюстративный пример:

  object MyClass { def main(args: Array[String]) { val numbers = List(5, 4, 8, 6, 2) val a = numbers.fold(0) { (z, i) => { println("fold val1 " + z +" val2 " + i) z + i } } println(a) val b = numbers.foldLeft(0) { (z, i) => println("foldleft val1 " + z +" val2 " + i) z + i } println(b) val c = numbers.foldRight(0) { (z, i) => println("fold right val1 " + z +" val2 " + i) z + i } println(c) } } 

Результат сам по себе:

 fold val1 0 val2 5 fold val1 5 val2 4 fold val1 9 val2 8 fold val1 17 val2 6 fold val1 23 val2 2 25 foldleft val1 0 val2 5 foldleft val1 5 val2 4 foldleft val1 9 val2 8 foldleft val1 17 val2 6 foldleft val1 23 val2 2 25 fold right val1 2 val2 0 fold right val1 6 val2 2 fold right val1 8 val2 8 fold right val1 4 val2 16 fold right val1 5 val2 20 25 
  • Анализ многострочных записей в Scala
  • Скрытые черты Scala
  • Использовать случай scala.concurrent.blocking
  • В чем разница между подclassами типа self-types и trait?
  • Scala String vs java.lang.String - вывод типа
  • В чем смысл classа Option ?
  • Обеспечивает ли JVM оптимизацию хвостовых вызовов?
  • Несоответствие типа Scala для понимания
  • Spark UDF с varargs
  • Как определить схему для настраиваемого типа в Spark SQL?
  • Как распечатать содержимое RDD?
  • Давайте будем гением компьютера.