이 시리즈는 "스칼라로 배우는 함수형 프로그래밍"을 TypeScript로 실습한 내용을 정리하고 있습니다
flatMap을 사용하면 여러 단계로 이루어진 계산을 수행하되 어떤 단계라도 실패하면 그 즉시 나머지 모든 과정이 취소시킬 수 있다.
흔한 사용 패턴은 map, flatMap, filter의 임의적인 조합을 이용해서 Option을 변환하고 제일 끝에서 getOrElse를 이용해서 오류 처리를 수행한다.
https://github.com/JsonKim/fpinscala-with-typescript/commit/bc5d3e7b41937d47d0b280a62dc88bc40d6d4b72
o.getOrElse(throw new Exception("FAIL"))
은 Option의 None을 예외로 처리하게 만드는 관용구이다. 복구 가능한 오류로 처리할 수 있을 만한 상황이라면 예외 대신 Option, Either등을 돌려주어서 호출자에게 유연성을 보장한다.
option과 같은 다루고자 하는 맥락이 인자의 순서 어디에 위치 하는가에 따라서 달리 해석해 볼 수 있다.
2개의 인자가 필요한 함수의 인자를 모두 Option을 받도록 만들려면 어떻게 해야할까? 해당 함수를 변경하면 관심사들이 얽혀서 한 계산이 항상 이전 계산의 성공 여부를 신경써야 한다. 이 함수의 호출자가 본문 안에서 명시적인 패턴 매칭을 이용할 수도 있지만 이러한 역할을 해주는 함수 map2를 만들자.
https://github.com/JsonKim/fpinscala-with-typescript/commit/da329817fbc09861fb89f8f9b3554fcb64f11067
map2가 인수 두 개인 어떤 함수라도 lift할 수 있는 것 처럼 map3, map4, ... 를 떠올릴 수 도있다. 뒤에서 나오겠지만 applicative functor가 이 문제를 해결한다.
https://github.com/JsonKim/fpinscala-with-typescript/commit/4c99922c63615c503172d96275450b5e77e2196c
https://github.com/JsonKim/fpinscala-with-typescript/commit/73c2b95f337f03bfdd490cf3c25265c29e97954c
어떤 리스트 List<A>
를 Option<B>
로 만들고 Option<B>
를 List<Option<B>>
로 결합하기 위해서 sequence를 사용하면 목록을 두 번 훑어야하기 때문에 비효율적이다.
이런 작업은 빈번하기 때문에 traverse라는 이름의 일반적인 함수로 만들어 사용한다. traverse 함수의 두번째 인자로 id를 주면 sequence함수를 만들 수 있다.
map, lift, sequence, traverse, map2, map3와 같은 함수들이 있으면 optional 값을 다루기 위해 기존 함수를 수정해야 할 일이 전혀 없어야 한다.