이 글은 책 Learn You a Haskell for Great Good을 읽고 정리한 것입니다.
함수 foldl의 모나드 버전은 foldM이다. foldl의 타입은 아래와 같다.
foldl :: (a -> b -> a) -> a -> [b] -> afoldl의 인자와 결과는 순서대로 아래와 같다.
(a -> b -> a): 인자가 두개인 함수a: 결과를 누적할 초기값[b]:fold를 수행할 리스트
아래와 같이 사용할 수 있다.
GHCi> foldl (\acc x -> acc + x) 0 [2,8,3,1]
14
foldM의 타입은 아래와 같다.
foldM :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m afoldM의 타입은 foldl와 비슷한데 첫번째 인자로 받는 함수의 결과 타입과 최종 결과 타입만 m a로 다르다.
리스트의 원소 값이 9보다 크면 실패한다는 Maybe 문맥을 추가해보자. 아래와 같이 함수 binSmalls를 정의할 수 있다.
binSmalls :: Int -> Int -> Maybe Int
binSmalls acc x
| x > 9 = Nothing
| otherwise = Just (acc + x)아래와 같이 foldM을 이용할 수 있다.
GHCi> foldM binSmalls 0 [2,8,3,1]
Just 14
GHCi> foldM binSmalls 0 [2,11,3,1]
Nothing
책에서 제시한 예제는 여기까지이고 아래와 같이 'Writer 값을 리턴하는 함수를 이용하면 재밌을 것이다' 라고 적혀있다.
Folding with a binary function that returns a
Writervalue is cool as well, because then you log whatever you want as your fold goes along its way.
한번 만들어보자.
binLog :: Int -> Int -> Writer [String] Int
binLog acc x = (acc + x, ["add " ++ show x ++ " to " ++ show acc])GHCi> foldM binLog 0 [1,2,3,4]
GHCi> runWriter $ foldM f 0 [1,2,3,4]
(10,["add 1 to 0","add 2 to 1","add 3 to 3","add 4 to 6"])
사랑해요 모나드 ㅎ