2013-04-19 4 views
32

fold 및 foldLeft와 각각 reduce 및 reduceLeft 작업 방법을 이해하려고합니다. foldfoldLeft대로 작동하지 않은 이유는 무엇입니까 예를스칼라 : fold vs foldLeft

scala> val r = List((ArrayBuffer(1, 2, 3, 4),10)) 
scala> r.foldLeft(ArrayBuffer(1,2,4,5))((x,y) => x -- y._1) 

scala> res28: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(5) 

scala> r.fold(ArrayBuffer(1,2,4,5))((x,y) => x -- y._1) 
<console>:11: error: value _1 is not a member of Serializable with Equals 
       r.fold(ArrayBuffer(1,2,4,5))((x,y) => x -- y._1) 

로 배와 foldLeft를 사용? Serializable with Equals은 무엇입니까? fold를 이해하고 foldLeft는 매개 변수 제네릭 유형 측면에서 약간 다른 API 서명을가집니다. 제발 조언. 감사.

+3

[fold fold와 foldLeft 또는 foldRight 사이의 차이점]? (http://stackoverflow.com/q/6253978) –

+0

어떤 스칼라 버전입니까? –

+0

내 스칼라 버전은 2.10.1입니다. – thlim

답변

54

fold (원래 병렬 계산을 위해 추가 된 방법)은 적용 할 수있는 유형 측면에서 foldLeft보다 강력하지 않습니다. 그 서명은 :이 폴딩이 수행되는 동안 유형이 콜렉션 요소의 형태의 슈퍼 타입이어야한다는 것을 의미

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

. foldLeft는 할 수 없지만

def foldLeft[B](z: B)(op: (B, A) => B): B 

이유는 fold 병렬로 구현 될 수 있다는 것이다. 이것은 foldLeft이 왼쪽에서 오른쪽으로 순차적으로가는 것을 의미하는 *Left 부분뿐만 아니라 연산자 op이 집계 유형 B을 요소 유형 A과 결합하는 방법 만 정의하므로 병렬로 계산 된 결과를 결합 할 수 없기 때문입니다. 그러나 B 유형의 두 집계를 결합하는 방법은 아닙니다. 집계 유형 A1은 요소 유형 A의 수퍼 유형 (즉, A1 >: A)이어야하므로 fold 메소드가이를 정의합니다. 이 수퍼 유형 관계는 같은 시간에 집계 및 요소를 접을 수 있으며 집계를 결합 할 수 있습니다. 둘 다 단일 연산자와 결합합니다.

그러나 집계와 요소 유형 간의이 수퍼 유형 관계는 또한 예에서 집계 유형 A1(ArrayBuffer[Int], Int)의 수퍼 유형이어야 함을 의미합니다. 집계의 0 요소는 ArrayBuffer[Int] 유형의 ArrayBuffer(1, 2, 4, 5)이므로 집계 유형은 두 가지의 상위 유형으로 추측됩니다. 즉, 튜플 및 배열 버퍼의 최소 상한 인 Serializable with Equals입니다.

일반적으로 임의의 유형에 대해 병렬 폴딩을 허용하려면 (순서가 잘못되어 있음) 두 개의 집계가 결합되는 방법을 정의해야하는 aggregate 메서드를 사용해야합니다. 귀하의 경우 : Btw는

r.aggregate(ArrayBuffer(1, 2, 4, 5))({ (x, y) => x -- y._1 }, (x, y) => x intersect y) 

reduce/reduceLeft로 예를 작성하려고 - 때문에 요소 유형 및이 두 가지 방법이 집계 유형의 슈퍼 타입 관계, 당신은 그것이 리드 것을 발견 할 것이다 설명 된 오류와 유사한 오류가 발생했습니다.

관련 문제