예외를 이용하지 않은 오류 처리 - Option (2)

Jason Kim·2020년 5월 6일
0

이 시리즈는 "스칼라로 배우는 함수형 프로그래밍"을 TypeScript로 실습한 내용을 정리하고 있습니다

기본적인 Option 함수들의 용례

flatMap을 사용하면 여러 단계로 이루어진 계산을 수행하되 어떤 단계라도 실패하면 그 즉시 나머지 모든 과정이 취소시킬 수 있다.
흔한 사용 패턴은 map, flatMap, filter의 임의적인 조합을 이용해서 Option을 변환하고 제일 끝에서 getOrElse를 이용해서 오류 처리를 수행한다.

연습문제 4.2

https://github.com/JsonKim/fpinscala-with-typescript/commit/bc5d3e7b41937d47d0b280a62dc88bc40d6d4b72

o.getOrElse(throw new Exception("FAIL"))은 Option의 None을 예외로 처리하게 만드는 관용구이다. 복구 가능한 오류로 처리할 수 있을 만한 상황이라면 예외 대신 Option, Either등을 돌려주어서 호출자에게 유연성을 보장한다.

예외 지향적 API의 Option 합성과 승급, 감싸기

option과 같은 다루고자 하는 맥락이 인자의 순서 어디에 위치 하는가에 따라서 달리 해석해 볼 수 있다.

  • map(option)
    • forall f a b. Functor f => (a -> b) -> f b
    • 오류가 발생하지 않고 Option안의 결과(가 있다면)를 변환하는데 사용한다. 오류 처리를 나중의 코드에 미루는 수단. option은 주어졌고, 함수를 인자로 받을 수 있다.
  • lift f = _ map f
    • forall f a b. Functor f => f a -> f b
    • 보통의 함수를 Option에 대해 작용하는 함수로 승급시켜 어떤 함수로 한 Option 값의 문맥 안에서 작용하도록 변환 할 수 있다. 이 경우는 함수가 주어졌고 option을 인자로 받을 수 있는 상태이다.

2개의 인자가 필요한 함수의 인자를 모두 Option을 받도록 만들려면 어떻게 해야할까? 해당 함수를 변경하면 관심사들이 얽혀서 한 계산이 항상 이전 계산의 성공 여부를 신경써야 한다. 이 함수의 호출자가 본문 안에서 명시적인 패턴 매칭을 이용할 수도 있지만 이러한 역할을 해주는 함수 map2를 만들자.

연습문제 4.3

https://github.com/JsonKim/fpinscala-with-typescript/commit/da329817fbc09861fb89f8f9b3554fcb64f11067

map2가 인수 두 개인 어떤 함수라도 lift할 수 있는 것 처럼 map3, map4, ... 를 떠올릴 수 도있다. 뒤에서 나오겠지만 applicative functor가 이 문제를 해결한다.

연습문제 4.4

https://github.com/JsonKim/fpinscala-with-typescript/commit/4c99922c63615c503172d96275450b5e77e2196c

연습문제 4.5

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 값을 다루기 위해 기존 함수를 수정해야 할 일이 전혀 없어야 한다.

0개의 댓글