맨위로가기

Fold (고차 함수)

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

Fold는 리스트의 각 요소를 결합하여 단일 값을 생성하는 고차 함수이다. 리스트의 쉼표를 특정 연산자로 대체하는 것으로 이해할 수 있으며, 왼쪽 또는 오른쪽으로 결합하는 방식에 따라 두 가지 주요 유형이 있다. 왼쪽 폴드는 초기 값과 리스트의 첫 번째 요소를 함수에 적용하고, 그 결과를 다음 요소와 함께 반복하며, 오른쪽 폴드는 리스트의 마지막 요소와 초기값을 함수에 적용하고, 그 결과를 이전 요소와 함께 반복한다.

Fold는 다양한 프로그래밍 언어에서 지원되며, 함수형 언어에서는 핵심 기능으로 제공된다. 또한 C#, C++, Java, Python, Ruby, JavaScript 등 객체 지향 및 스크립트 언어에서도 폴드와 유사한 기능을 찾아볼 수 있다. 폴드는 데이터 구조의 구조적 구성 요소를 함수와 값으로 대체하는 구조적 변환으로 볼 수 있으며, 다양한 자료형에 적용될 수 있다. 엄격한 평가와 지연 평가 환경에서의 평가 순서에 따라 효율성이 달라질 수 있으며, 다형성을 가지므로 다른 함수를 표현하는 데 사용될 수 있다.

더 읽어볼만한 페이지

  • 고차 함수 - 커링
    커링은 다수의 인수를 취하는 함수를 단일 인수를 취하는 함수들의 연속으로 변환하는 기법으로, 함수형 프로그래밍에서 다인수 함수를 분해하여 적용하는 방식이며, 논리학과 컴퓨터 과학에서 널리 활용되는 중요한 개념이다.
  • 고차 함수 - Map (고차 함수)
    Map 고차 함수는 함수형 프로그래밍에서 컬렉션의 각 요소에 함수를 적용해 새로운 컬렉션을 생성하는 기능으로, Lisp에서 처음 소개된 후 다양한 언어에서 구현되어 요소별 연산을 간결하게 표현하며, 구현 방식과 기능은 언어별로 차이가 있다.
  • 재귀 - 무한 루프
    무한 루프는 컴퓨터 프로그램에서 루프가 종료되지 않고 무한히 반복되는 현상으로, 프로그램 오류나 의도적인 경우에 발생하며 시스템 응답 불능을 초래하거나 특정 상황에서 사용되기도 한다.
  • 재귀 - 점화식
    점화식은 수열의 각 항을 이전 항들의 함수로 표현하는 방정식으로, 피보나치 수열, 로지스틱 맵, 이항 계수 등의 예시가 있으며, 선형대수학이나 Z변환 등을 이용하여 풀고 다양한 분야에 응용된다.
Fold (고차 함수)
개요
종류고차 함수
정의리스트의 원소들을 결합하는 함수
활용리스트 축소
데이터 집계
특징재귀적 또는 반복적 연산 수행
함수형 프로그래밍
중요성함수형 프로그래밍에서 중요한 역할 수행
불변성데이터 불변성을 유지하며 안전한 연산 가능
연산 방식
기본 원리초기값과 리스트의 각 원소를 순차적으로 함수에 적용하여 결과 누적
예시리스트의 모든 숫자 합 계산
문자열 연결
프로그래밍 언어별 구현
공통 기능대부분의 함수형 프로그래밍 언어에서 제공
사용 예시Haskell의 `foldl`, `foldr`
Scala의 `foldLeft`, `foldRight`
Python의 `functools.reduce`
장점
코드 간결성복잡한 로직을 간결하게 표현 가능
재사용성다양한 데이터 타입과 연산에 적용 가능
단점
가독성초기 학습 곡선이 높고, 복잡한 연산 시 가독성 저하 가능
성능잘못 사용 시 성능 저하 유발 가능
기타
관련 개념map
filter
주의사항초기값 설정 및 연산 순서에 주의해야 함

2. 역사적 배경

폴드의 개념은 함수형 프로그래밍 언어의 발전과 함께 나타났다.

3. 리스트에 관하여

리스트 `[1, 2, 3, 4, 5]`를 덧셈 연산자로 폴드하면 15가 되는데, 이는 리스트의 모든 원소의 합이다.[1] 이를 쉼표를 '+' 연산으로 대체하는 것으로 생각하면, `1 + 2 + 3 + 4 + 5`가 된다.[1]

'+' 연산은 결합 법칙이 성립하므로, 괄호의 배치에 관계없이 결과는 동일하다. 그러나 결합 법칙이 성립하지 않는 이진 함수에서는 원소들이 결합되는 순서가 최종 결과에 영향을 줄 수 있다. 리스트에 대해 폴드를 수행하는 방법에는 오른쪽 폴드왼쪽 폴드 두 가지가 있다.


  • 오른쪽 폴드: 첫 번째 원소를 나머지 원소들을 재귀적으로 결합한 결과와 결합한다.
  • 왼쪽 폴드: 마지막 원소를 제외한 모든 원소들을 재귀적으로 결합한 결과를 마지막 원소와 결합한다.


이는 Haskell (프로그래밍 언어) 또는 프롤로그에서 이진 연산자가 오른쪽 결합 또는 왼쪽 결합을 하는 것에 해당한다. 오른쪽 폴드의 경우 합은 `1 + (2 + (3 + (4 + 5)))`와 같이, 왼쪽 폴드의 경우 `(((1 + 2) + 3) + 4) + 5`와 같이 괄호로 묶인다.

초기값을 사용하면 편리하다. 오른쪽 폴드는 리스트의 끝에, 왼쪽 폴드는 리스트의 첫 번째 원소와 처음에 결합되는 초기값을 갖는다. 덧셈의 경우 덧셈 항등원인 0을 초기값으로 선택하면, 오른쪽 폴드는 `1 + (2 + (3 + (4 + (5 + 0))))`, 왼쪽 폴드는 `((((0 + 1) + 2) + 3) + 4) + 5`가 된다. 곱셈의 항등원은 1이며, 이를 초기값으로 사용하면 `1 * 1 * 2 * 3 * 4 * 5 = 120 = 5!`가 된다.

3. 1. 선형 폴드

선형 폴드는 리스트의 각 요소를 순차적으로 처리하며, 연산을 왼쪽에서 오른쪽으로 (좌측 폴드, `foldl`) 또는 오른쪽에서 왼쪽으로 (우측 폴드, `foldr`) 수행한다.

  • 좌측 폴드 (foldl): 초기값과 리스트의 첫 번째 요소를 함수에 적용하고, 그 결과를 다음 요소와 함께 다시 함수에 적용하는 과정을 반복한다.
  • 우측 폴드 (foldr): 리스트의 마지막 요소와 초기값을 함수에 적용하고, 그 결과를 이전 요소와 함께 다시 함수에 적용하는 과정을 반복한다.


예를 들어, 리스트 `[1, 2, 3, 4, 5]`를 덧셈 연산자로 폴드하면 15가 된다. 이는 리스트의 쉼표를 '+' 연산자로 대체하는 것과 유사하며, `1 + 2 + 3 + 4 + 5`가 된다.[1]

  • 우측 폴드는 `1 + (2 + (3 + (4 + (5 + 0))))` 와 같이 계산된다. (초기값 0)
  • 좌측 폴드는 `((((0 + 1) + 2) + 3) + 4) + 5` 와 같이 계산된다. (초기값 0)


Haskell (프로그래밍 언어)에서 `foldl`과 `foldr` 함수는 다음과 같이 표현될 수 있다.

```haskell

foldl :: (b -> a -> b) -> b -> [a] -> b

foldl f z [] = z

foldl f z (x:xs) = foldl f (f z x) xs

```

  • 빈 리스트의 경우 결과는 초기값(`z`)이다.
  • 그렇지 않으면 이전 초기값과 첫 번째 요소에 함수 `f`를 적용한 결과 값을 새로운 초기값으로 사용하여 리스트의 나머지 부분을 재귀적으로 처리한다.


```haskell

foldr :: (a -> b -> b) -> b -> [a] -> b

foldr f z [] = z

foldr f z (x:xs) = f x (foldr f z xs)

```

  • 빈 리스트의 경우 결과는 초기값(`z`)이다.
  • 그렇지 않으면 첫 번째 요소와 나머지 부분을 재귀적으로 처리한 결과에 함수 `f`를 적용한다.


좌측 폴드는 꼬리 재귀 최적화가 가능하여 메모리 효율성이 높을 수 있지만, 무한 리스트에는 적용할 수 없다. 반면 우측 폴드는 게으른 계산을 이용하면 무한 리스트에도 적용 가능하지만, 꼬리 재귀 최적화가 어려워 메모리 효율성이 떨어질 수 있다.

게으른 계산을 사용하는 왼쪽 폴드의 경우, 새로운 초기 매개변수가 재귀 호출 전에 평가되지 않아 스택 오버플로를 유발할 수 있다. 이를 방지하기 위해 Haskell에서는 `foldl'` (작은따옴표, 'prime'으로 발음) 함수를 제공하여 재귀 호출 전에 초기 매개변수의 평가를 강제한다.

3. 2. 트리형 폴드

트리형 폴드는 리스트를 이진 트리 형태로 구성하여 연산을 수행한다. 각 노드에서 함수를 적용하여 부분 결과를 계산하고, 이를 상위 노드에서 다시 결합하는 방식으로 진행된다. 이항 연산 ''f''가 결합 법칙을 만족하면, 연산 방식의 세부 사항은 달라도 괄호 배치에 관계없이 같은 값을 가진다.[1]

함수가 마그마인 경우, 즉 타입이 대칭적이고(a → a → a), 결과 타입이 리스트 요소의 타입과 동일한 경우, 괄호를 임의의 방식으로 배치하여 중첩된 하위 표현식의 이진 트리를 만들 수 있다. 이는 ''f''가 비엄격적일 경우 효율성에 큰 영향을 줄 수 있다.[1]

선형 폴드는 노드 지향적이며 리스트의 각 노드에 대해 일관된 방식으로 작동하는 반면, 트리형 폴드는 전체 리스트 지향적이며 노드 ''그룹'' 전체에 대해 일관된 방식으로 작동한다.[1]

리스트는 유한 및 무한히 정의된 리스트 모두에 대해 트리 형태 방식으로 폴드될 수 있다. foldi 함수의 경우, ''무한히'' 정의된 리스트에서 실행이 중단되지 않도록 하려면 함수 f가 적어도 전부 또는 즉시 두 번째 인수의 값을 ''항상'' 요구해서는 안 된다.[1]

유한 목록의 경우, 합병 정렬은 트리 형태의 폴딩을 사용하여 정의할 수 있다.

3. 3. 비어 있지 않은 리스트를 위한 특별한 폴드

초기값이 필요 없는 경우, 비어 있지 않은 리스트에 대해 `foldl1`과 `foldr1`과 같은 함수를 사용할 수 있다. `foldl1`은 리스트의 첫 번째 요소를 초기값으로 사용하고, `foldr1`은 리스트의 마지막 요소를 초기값으로 사용한다.[1] 이러한 함수들은 초기값을 명시적으로 지정할 필요가 없어 편리하지만, 비어 있는 리스트에는 적용할 수 없다.

이러한 fold는 형식 대칭 이진 연산을 사용한다. 즉, 두 인수와 결과의 형식이 같아야 한다. Richard Bird는 2010년 저서에서[2] "비어 있지 않은 목록에 대한 일반적인 fold 함수" `foldrn`을 제안했는데, 이 함수는 추가 인수 함수를 적용하여 마지막 요소를 변환하여, fold 자체를 시작하기 전에 결과 형식의 값으로 변환한다. 따라서 일반적인 `foldr`과 같이 형식 비대칭 이진 연산을 사용하여 목록 요소 형식과 다른 형식의 결과를 생성할 수 있다.

```haskell

foldl1 f [x] = x

foldl1 f (x:y:xs) = foldl1 f (f x y : xs)

foldr1 f [x] = x

foldr1 f (x:xs) = f x (foldr1 f xs)

foldt1 f [x] = x

foldt1 f (x:y:xs) = foldt1 f (f x y : pairs f xs)

foldi1 f [x] = x

foldi1 f (x:xs) = f x (foldi1 f (pairs f xs))

4. 다양한 언어에서의 폴드

. initval,arrayverb/ array,initval''verb''~/>. arrayverb/ arrayJuliafoldl(op, itr; [init])foldr(op, itr; [init])foldl(op, itr)foldr(op, itr)KotlinIterable.fold(initval, func)Iterable.foldRight(initval, func)Iterable.reduce(func)Iterable.reduceRight(func)Logtalkfold_left(Closure, Initial, List, Result)fold_right(Closure, Initial, List, Result)Maplefoldl(func, initval, sequence)foldr(func, initval, sequence)MathematicaFold[func, initval, list]Fold[func, initval, Reverse[list]]Fold[func, list]Fold[func, Reverse[list]]NestWhileList[func,, initval, predicate]MATLABfold(@func, list, defaultVal)fold(@func, flip(list), defaultVal)fold(@func, list)fold(@func, flip(list))Maximalreduce(func, list, initval)rreduce(func, list, initval)lreduce(func, list)rreduce(func, list)Mythrylfold_left func initval list vector::fold_left func initval vectorfold_right func initval list vector::fold_right func initval vectorOz{FoldL List Func InitVal}{FoldR List Func InitVal}PARI/GPfold( f, A )Perlreduce block initval, listreduce block listPHParray_reduce(array, func, initval)array_reduce(array_reverse(array), func, initval)array_reduce(array, func)array_reduce(array_reverse(array), func)RReduce(func, list, initval)Reduce(func, list, initval, right=TRUE)Reduce(func, list)Reduce(func, list, right=TRUE)Rustiterator.fold(initval, func)iterator.rev().fold(initval, func)스몰토크aCollection inject: aValue into: aBlockaCollection reduce: aBlockSwiftarray.reduce(initval, func) reduce(sequence, initval, func)array.reverse().reduce(initval, func)XPath 3.1Xtenditerable.fold(initval,[func])iterable.reduce[func]


4. 1. 함수형 프로그래밍 언어

(initval /: list)(func)list.foldRight(initval)(func)
(list :\ initval)(func)list.reduceLeft(func)list.reduceRight(func)스칼라의 기호 접기 구문은 접기 연산을 설명하는 데 일반적으로 사용되는 왼쪽 또는 오른쪽 기울임 트리와 유사하도록 의도되었지만,[9] 이후 도미노 쓰러뜨리기를 보여주는 그림으로 재해석되었다.[10] 콜론은 왼쪽 피연산자에서 인픽스 연산자를 메서드로 호출하고 오른쪽 피연산자를 인수로 전달하거나, 연산자의 마지막 문자가 콜론인 경우 그 반대의 경우(여기서는 대칭적으로 적용됨)와 같은 일반적인 스칼라 구문 메커니즘에서 비롯된다.F#List.fold func initval list
Seq.fold func initval sequenceList.foldBack func list initvalList.reduce func list
Seq.reduce func sequenceList.reduceBack func listSeq.unfold func initvalClojure(reduce func initval list)(reduce func initval (reverse list))(reduce func list)(reduce func (reverse list))[https://clojure.github.io/clojure/clojure.core-api.html#clojure.core.reducers/fold clojure.core.reducers/fold]도 참조.OCamlList.fold_left func initval list
Array.fold_left func initval arrayList.fold_right func list initval
Array.fold_right func array initvalStandard MLfoldl func initval list
Array.foldl func initval arrayfoldr func initval list
Array.foldr func initval array제공된 함수는 인수를 튜플로 받는다. foldl의 경우, 폴딩 함수는 foldr과 동일한 순서로 인수를 받는다.ElmList.foldl(Fun, Accumulator, List)List.foldr(Fun, Accumulator, List)List API [http://package.elm-lang.org/packages/elm-lang/core/3.0.0/List#foldr]도 참조Erlanglists:foldl(Fun, Accumulator, List)lists:foldr(Fun, Accumulator, List)LFE(lists:foldl func accum list)(lists:foldr func accum list)Racket(foldl func initval list)(foldr func initval list)Scheme R6RS(fold-left func initval list)
(vector-fold func initval vector)(fold-right func initval list)
(vector-fold-right func initval vector)(reduce-left func defaultval list)(reduce-right func defaultval list)(unfold p f g seed [tail-gen])
unfold-right p f g seed [tail]
(vector-unfold f length initial-seed ···)
(vector-unfold-right f length initial-seed ···)srfi/1 srfi/43


4. 2. 객체지향 프로그래밍 언어

C# 3.0, C++, Java 8+ 등 객체지향 프로그래밍 언어들도 최근 버전에서 폴드와 유사한 기능을 추가하여 함수형 프로그래밍 스타일을 지원하고 있다.

C#, C++, Java에서 제공하는 폴드 관련 기능은 다음과 같다.

언어Left foldRight foldLeft fold (초기값 없음)Right fold (초기값 없음)비고
C# 3.0ienum.Aggregate(initval, func)ienum.Reverse().Aggregate(initval, func)ienum.Aggregate(func)ienum.Reverse().Aggregate(func)Aggregate는 확장 메서드이며, ienum은 `IEnumerable`이다. 모든 .NET 언어에서 적용된다.
C++std::accumulate(begin, end, initval, func)std::accumulate(rbegin, rend, initval, func)헤더 ``에 있으며, begin, end, rbegin, rend는 반복자이다. func함수 포인터 또는 함수 객체가 될 수 있다.
C++17(initval op ... op pack)(pack op ... op initval)(... op pack)(pack op ...)Fold 표현식 (단, 가변 템플릿에 한함): op는 이항 연산자이며 (두 op 모두 동일해야 함), pack은 확장되지 않은 파라미터 팩이다.
C++23std::ranges::fold_left(range, initval, func)std::ranges::fold_right(range, initval, func)std::ranges::fold_left_first(range, func)std::ranges::fold_right_last(range, func)std::ranges::fold_left_first와 std::ranges::fold_right_last는 모두 range가 비어있는 경우를 고려하여 `std::optional`을 반환한다.
Java 8+stream.reduce(initval, func)stream.reduce(func)


4. 3. 스크립트 언어

.inject(initval, &block)
enum.reduce(initval, &block)enum.reverse_each.inject(initval, &block)
enum.reverse_each.reduce(initval, &block)
enum.inject(&block)
enum.reduce(&block)
enum.reverse_each.inject(&block)
enum.reverse_each.reduce(&block)


5. 구조적 변환으로서의 폴드

폴드는 데이터 구조의 구조적 구성 요소를 함수와 값으로 일관되게 대체하는 것으로 이해할 수 있다. 예를 들어, 리스트는 많은 함수형 언어에서 두 가지 기본 요소로 구성된다. 모든 리스트는 빈 리스트(일반적으로 ''nil''이라고 함)이거나, 다른 리스트 앞에 요소를 접두사로 추가하여 구성되며, 이는 ''cons'' 노드 ( Cons(X1,Cons(X2,Cons(...(Cons(Xn,nil))))) )라고 불리며 cons 함수를 적용한 결과이다(Haskell에서는 콜론 (:)으로 표시됨).[1]

리스트에 대한 폴드는 리스트 끝에 있는 ''nil''을 특정 값으로 ''대체''하고 각 ''cons''를 특정 함수로 ''대체''하는 것으로 볼 수 있다. 이러한 대체는 다음 그림과 같이 나타낼 수 있다.



각 노드의 두 링크 순서를 결합 함수에 입력할 때 뒤집는 방식으로 일관되게 구조적 변환을 수행하는 또 다른 방법도 있다.



이 그림들은 시각적으로 리스트의 ''오른쪽'' 및 ''왼쪽'' 폴드를 보여준다. 또한 foldr (:) []가 리스트에 대한 항등 함수(Lisp 용어로는 ''얕은 복사'')라는 사실을 강조한다. ''cons''를 cons로, ''nil''을 nil로 대체하면 결과가 변경되지 않기 때문이다. 왼쪽 폴드 다이어그램은 리스트를 뒤집는 쉬운 방법인 foldl (flip (:)) []을 제안한다. 추가할 요소가 이제 결합 함수의 오른쪽 매개변수이므로, cons에 대한 매개변수를 뒤집어야 한다.

이러한 관점은 다양한 종류의 트리와 같은 다른 대수적 자료형 및 구조에 대한 폴드와 유사한 함수를 설계하는 간단한 경로를 제공한다. 제공된 함수로 데이터 유형의 생성자를 재귀적으로 대체하고, 유형의 모든 상수 값을 제공된 값으로 대체하는 함수를 작성한다. 이러한 함수는 일반적으로 카타모피즘이라고 한다.

6. 평가 순서 고려 사항

엄격한 평가를 사용하는 프로그래밍 언어에서는 좌측 폴드(foldl)가 꼬리 재귀 최적화를 통해 효율적으로 계산될 수 있다. 꼬리 재귀는 함수의 마지막 연산이 자기 자신을 호출하는 형태이므로, 반복문으로 변환하여 스택 메모리 사용을 줄일 수 있기 때문이다.

반면, 지연 평가를 사용하는 언어에서는 우측 폴드(foldr)가 무한 리스트에 적용 가능하다. 지연 평가는 실제로 값이 필요할 때까지 계산을 미루는 방식이므로, 우측 폴드는 리스트의 앞부분부터 필요한 만큼만 계산하고 나머지는 필요할 때까지 계산하지 않을 수 있다. 예를 들어, `head == foldr (\a b->a) (error "empty list")`와 같이 사용하여 무한 리스트의 첫 번째 요소를 얻을 수 있다.

하지만 좌측 폴드는 지연 평가 환경에서 스택 오버플로를 일으킬 수 있으므로 주의해야 한다. 좌측 폴드는 리스트의 끝까지 도달해야 계산을 시작하는데, 지연 평가에서는 중간 계산 결과를 저장하지 않고 표현식 형태로 쌓아두기만 하기 때문이다. 따라서 매우 긴 리스트나 무한 리스트에 좌측 폴드를 적용하면 스택 오버플로가 발생할 수 있다.

이러한 문제를 해결하기 위해, 일부 언어에서는 좌측 폴드의 엄격한 변형(예: Haskell의 `foldl'`)을 제공한다. 이 함수는 재귀 호출 전에 중간 결과를 강제로 계산하여 스택 오버플로를 방지한다. 꼬리 재귀와 결합하면, 이러한 엄격한 좌측 폴드는 상수 공간에서 연산을 수행할 수 있게 해준다.

7. 보편성(Universality)

폴드는 데이터 구조의 구성 요소를 함수와 값으로 일관되게 대체하는 것으로 볼 수 있다. 예를 들어, 리스트는 빈 리스트(`nil`, `[]`) 또는 다른 리스트 앞에 요소를 추가(`cons` 노드)하여 구성된다. 리스트에 대한 폴드는 리스트 끝의 `nil`을 특정 값으로, 각 `cons`를 특정 함수로 대체하는 것이다.

각 노드의 링크 순서를 뒤집어 구조적 변환을 수행하는 방법도 있다.

이 그림들은 리스트의 오른쪽 및 왼쪽 폴드를 시각적으로 보여준다. `foldr (:) []`는 리스트의 항등 함수(얕은 복사)이다. `cons`를 `cons`로, `nil`을 `nil`로 대체하면 결과가 변경되지 않기 때문이다. 왼쪽 폴드는 리스트를 뒤집는 `foldl (flip (:)) []`을 제안한다. `cons`에 대한 매개변수를 뒤집어야 하는데, 추가할 요소가 이제 결합 함수의 오른쪽 매개변수이기 때문이다. `foldr`을 사용하여 고차 맵 함수를 작성할 수도 있다.

```haskell

map f = foldr ((:) . f) []

```

여기서 점(.)은 함수 합성 연산자이다.

이러한 관점은 트리와 같은 다른 대수적 자료형에 대한 폴드 함수를 설계하는 경로를 제공한다. 데이터 유형의 생성자를 제공된 함수로 재귀적으로 대체하고, 상수 값을 제공된 값으로 대체하는 함수를 작성한다. 이러한 함수는 카타모피즘이라고 한다.

폴드는 다형 함수이다. 다음 정의를 갖는 모든 ''g''에 대해:

```haskell

g [] = v

g (x:xs) = f x (g xs)

```

''g''는 다음과 같이 표현될 수 있다.[12]

```haskell

g = foldr f v

```

또한, 무한 리스트가 있는 느긋한 언어에서는 고정점 조합자가 폴드를 통해 구현될 수 있으며, 이는 반복이 폴드로 줄어들 수 있음을 증명한다.[13]

```haskell

y f = foldr (\_ -> f) undefined (repeat undefined)

참조

[1] 웹사이트 Haskell unit 6: The higher-order fold functions ! Antoni Diller https://www.cantab.n[...] 2023-04-04
[2] 서적 Pearls of Functional Algorithm Design Cambridge University Press 2010
[3] 웹사이트 Array.prototype.reduce() - JavaScript ! MDN https://developer.mo[...] 2024-01-16
[4] 웹사이트 fold - Kotlin Programming Language https://kotlinlang.o[...] Jetbrains 2019-03-29
[5] 웹사이트 reduce - Kotlin Programming Language https://kotlinlang.o[...] Jetbrains 2019-03-29
[6] 웹사이트 Result - Kotlin Programming Language https://kotlinlang.o[...] Jetbrains 2019-03-29
[7] 문서
[8] 웹사이트 Iterator in core::iter https://doc.rust-lan[...] Rust Team 2021-06-22
[9] 뉴스 Re: Blog: My verdict on the Scala language http://permalink.gma[...] 2013-10-14
[10] 웹사이트 An intuitive feel for Scala's /: operator (foldLeft) https://nicholasster[...] 2016-06-24
[11] 웹사이트 Fold API - Scala Standard Library https://www.scala-la[...] 2018-04-10
[12] 간행물 A tutorial on the universality and expressiveness of fold http://www.cs.nott.a[...] 2009-03-26
[13] 간행물 Getting a Fix from the Right Fold http://www.haskell.o[...] 2011-05-01
[14] 웹인용 Base https://opensource.j[...] Jane Street Capital 2019-02-26
[15] 문서 "array:fold-left" https://www.w3.org/T[...]
[16] 문서 fold-left https://www.w3.org/T[...]
[17] 문서 "array:fold-right" https://www.w3.org/T[...]
[18] 문서 fold-right https://www.w3.org/T[...]



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com