foldr 이랑 fold 에 대해서 알지?
scanr 이랑 scanl 에 대해서도 알거야
폴드는 리듀스야
foldr f z [..] 로 써. f를 z와 첫번째 원소에 적용하고, 결괏값과 두번째 원소를 f 돌리고, 다시 결과랑 세번째 원소를 f 돌리고 ~~~ 그 결과를 반환.
첫번째 원소를 왼쪽부터 세면 foldl , 첫번째 원소를 우측부터 세면 foldr
리스트는 재귀적으로 왼쪽에서 오른쪽으로밖에 풀 수 없어. 따라서 이 방향이라는게 생각보다 재밌어. 방향때문에 특정 성질이 결정되기도 하지.
예를들자면, foldl 은 무한을 다룰 수 없지만 fodlr은 무한을 다룰 수 있어.
스캔은 fold가 계산하는 중간과정들을 전부다 리스트로 담아서 반환하는 애야.
스캔의 방향은 r l 이 있어 연산방향을 의미해.
근데 리스트에 계산결과를 축적하는 방향이란것도 있어. 왼쪽 오른쪽이 있음.
즉,
Foldl (+) 0 [1 2 3 4 5] 라면, 계산은 1, 3, 6, 10, 15로 작동하지만
리스트에
1, 3, 6, 10, 15 로 담을지 15, 10, 6, 3, 1 로 담을지가 또 다르단말야.
내가 직관적으로 scanl 과 scanr 을 만들었을때는 전부 가장 왼쪽에 총 연산이 담겨있는 방향으로 짰어.
근데 scanl은 역순이거든? 점점 연산을 합쳐나가는 방식으로 되어있거든?
그래서 나는 구현하고나서, 아 scanl은 여기에 리버스 붙이나보다 했었음. (리버스는 리스트를 역순으로 반환하는 함수야. 그냥 그거 붙인줄 알았어)
근데 구현을 뜯어보니까
진짜로 나랑 반대방향으로 리스트를 빌드업하더라고??
재귀적으로 빌드 자체가 반대방향으로 빌드업을 해.
너무 신기했지
어 뭐지?? 구현이 여러개일수 있다는건 알고 있었는데, 역방향도 가능한거구나
근데 여기서 차릿! 하고 내 뇌리를 스쳐가는 일이 있었는고 하니,
이거 scanr 도 내가 만든거 반대방향이 있다!!!
와 그 반대방향을 만드는데 조낸 애먹었음.
코드는 게시물로 따로 올리겠음
댓글 0