2012-01-29 2 views
2

Это обычное явление, когда нужно накапливать некоторые данные. То, как я привык это делать, - это добавить куски данных в массив. Но это плохая практика в scala, так как я могу избежать этого?scala: как избежать мутации?

+1

Было бы неплохо, если бы вы дали нам примерный код того, чего вы пытаетесь достичь ... для некоторых распространенных случаев 'foldLeft' /' foldRight' выполняет эту работу: http: //www.scala-lang .org/api/current/scala/collection/immutable/List.html # foldLeft – tenshi

+2

Вопрос чрезвычайно широк. Просьба прояснить это, привести пример и т. Д. –

ответ

4

Ну, есть два общих способа борьбы с накоплением: рекурсия и складчатость. Давайте рассмотрим очень простые примеры каждого из них, чтобы вычислить сумму значений списка.

def sumRecursively(list: List[Int]): Int = { 
    def recurse(list: List[Int], acc: Int): Int = 
    if (list.isEmpty) acc 
    else recurse(list.tail, acc + list.head) 
    recurse(list, 0) 
} 

def sumFolding(list: List[Int]): Int = 
    list.foldLeft(0){ case (acc, n) => acc + n } 

Существует много вариантов этого, которые лучше обрабатывают один случай.

+0

Кажется странным называть эти «два» пути, поскольку сгибание - это просто абстракция определенного шаблона рекурсии. –

+0

@ DanBurton Если вы думаете о сбрасывании как о катаморфизме рекурсивного типа, то вы не будете задавать этот вопрос, не так ли? Сгиб - это цикл, который касается мира в целом. –

2

Собственно, это не так. Вы можете использовать Vector в scala, который является частью пакета scala.collection.immutable по умолчанию. Это создаст неизменяемую коллекцию, которая возвращает новый (другой) экземпляр при каждом добавлении к нему.

Дополнительная информация:

http://www.scala-lang.org/docu/files/collections-api/collections_15.html

2

Для наиболее распространенных применений, «карты» и операции «flatMap» используются для функционально генерации структур данных. Оба начинают с одной структуры данных, применяют некоторую операцию к каждому элементу в ней и возвращают новую структуру данных той же формы, что и оригинал. Они отличаются тем, как заполняется новая структура данных. Эти два являются настолько распространенными и настолько мощными, что Scala включает в себя специальный синтаксис, для понимания, для их поддержки. Понимание на первый взгляд внешне похоже на Java-стиль for-loop, но фактически компилируется в ряд вызовов map и flatMap (среди нескольких других).

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

Стоит также отметить, что как «карта», так и «плоская карта» фактически особые случаи другой, более мощной функции: «свернуть». «fold» (реализованные как «foldLeft», так и «foldRight», по техническим причинам) могут использоваться как для создания структур данных, так и для их разрушения.