Vài điều cần đề cập ở đây, trước khi đưa ra câu trả lời thực tế:
- Câu hỏi của bạn không liên quan gì
left
, đó là về sự khác biệt giữa giảm và gấp
- Sự khác biệt hoàn toàn không phải là việc thực hiện, chỉ cần nhìn vào chữ ký.
- Câu hỏi không liên quan gì đến Scala nói riêng, đó là về hai khái niệm lập trình chức năng.
Quay lại câu hỏi của bạn:
Đây là chữ ký của foldLeft
(cũng có thể foldRight
là điểm mà tôi sẽ thực hiện):
def foldLeft [B] (z: B)(f: (B, A) => B): B
Và đây là chữ ký của reduceLeft
(một lần nữa hướng không quan trọng ở đây)
def reduceLeft [B >: A] (f: (B, A) => B): B
Hai cái này trông rất giống nhau và do đó gây ra sự nhầm lẫn. reduceLeft
là một trường hợp đặc biệt củafoldLeft
(điều này có nghĩa là đôi khi bạn có thể diễn đạt điều tương tự bằng cách sử dụng một trong hai).
Khi bạn gọi reduceLeft
say trên một List[Int]
nghĩa đen, nó sẽ giảm toàn bộ danh sách các số nguyên thành một giá trị duy nhất, sẽ thuộc loạiInt
(hoặc siêu kiểu Int
, do đó [B >: A]
).
Khi bạn gọi foldLeft
nói trên mộtList[Int]
nó sẽ gấp toàn bộ danh sách (tưởng tượng cuộn một mảnh giấy) thành một giá trị duy nhất, nhưng giá trị này không nhất thiết phải liên quan đến Int
(do đó [B]
).
Đây là một ví dụ:
def listWithSum(numbers: List[Int]) = numbers.foldLeft((List.empty[Int], 0)) {
(resultingTuple, currentInteger) =>
(currentInteger :: resultingTuple._1, currentInteger + resultingTuple._2)
}
Phương pháp này lấy một List[Int]
và trả về một Tuple2[List[Int], Int]
hoặc (List[Int], Int)
. Nó tính toán tổng và trả về một tuple với danh sách các số nguyên và đó là tổng. Bằng cách này, danh sách được trả lại, bởi vì chúng tôi đã sử dụng foldLeft
thay vì foldRight
.
Xem One Fold để thống trị tất cả để có giải thích sâu hơn.