FP(Functional Programming) - Either

cfop·2020년 10월 13일
0

Either Monad

값이 올바르냐, 올바르지 않냐 두 상태를 갖는 모나드 입니다.

Maybe 모나드로도 가능하지 않나?

가능 하긴 합니다. 몇가지 방법을 생각 해 볼 수 있습니다.

  1. 값을 그냥 다 넣는데, 내가 원하는 값만 mapping된 함수에서 분기처리 하여 로직 수행
  2. 내가 원하는 값이 아니면 다 null처리

이정도겠네요, 근데 조금 다른 상황을 생각해보면,,

지금 당장 생각 나는 것은 에러 메시지 같은 거겠네요, 에러가 나면 당장 프로그램을 멈추기를 원치 않고 에러 메시지(throw new Error)를 갖고 함수 mapping 진행(logging이나 뭐..)을 원한다면 Maybe 모나드로 다루기에는 부적절 함을 알 수 있습니다.

Maybe()
.chain((v)=>{
    try{
      logic...
      return ..
    }catch(e){
      return Maybe.nothing()
    }
})

이렇게 할 수는 있는데, 메시지를 갖고 logging하고 싶은데 null이 되어 버리네요. chain 함수 안에서 error 메시지를 가지고 외부 함수와 소통하는것은 함수의 순수성에 위배 됩니다.

Maybe()
.chain((v)=>{
    try{
      logic...
      return ..
    }catch(e){
      return Maybe(e.message)
    }
})

이래도 되긴 하는데 이게 에러인 것을 다음 연결된 함수에서 판명해야 합니다.
이래저래 하면 안될 건 없을 것 같습니다. 안되는게 어디 있겠습니까 이렇게 저렇게 하면 다 해결이 가능 하지요.

두 가지 상태, Right, Left

Right라는 말은 중의적인 단어이죠, 옳다 라는 뜻도 있습니다. 그래서 Right는 내가 원하는 값이 담긴 상태라고 정의 합니다

Left는 Right의 반대 입니다. 내가 원하는 상황에서 나온 값이 아닌 다른 값이 있는 상태 입니다.

Either 모나드의 interface


Right, Left 모두 같은 Either 모나드의 interface를 따릅니다. 자세히 보면 Maybe 모나드와 interface가 대동소이 함을 알 수 있습니다. 둘 사이의 호환을 위해서입니다.

Either Right 상태의 구현

maybe랑 거의 똑같습니다. 차이가 있다면 right는 map 결과가 right입니다. maybe는 내부에 값에 따라 some, nothing을 분기 했는데, maybe는 순수한 상태만 갖고 분기 로직은 외부로 뺀 케이스 입니다.

Either Left 상태의 구현


left도 마찬가지 입니다.

catch 함수는 뭐에요?

Right 상태 에서는 catch 함수의 결과는 자기 자신의 값이 담긴 right인 반면, left는 catch에 등록된 어떤 함수의 결과 입니다. left는 주로 어떤 로직에 의한 에러를 받는 용도이기 때문에 catch 함수에 이런 차이가 있습니다.

Either tryCatch 함수

에러가 있으면 left, 없으면 right를 리턴 합니다. left일때는 left의 catch 함수에 등록된 함수가 뭔가 할 일이 있는 것이죠.

예제

이렇게 외부에서 left, right를 가르는 로직을 분리 하고, left, right는 상태만 갖는 것을 알 수 있습니다.

의문점

  1. Maybe랑 굉장히 비슷해 보이는데, 이중에 하나만 골라서 꼭 써야 하나요? 이 두개를 연결할 수는 없나요?

우선적인 답변

  1. 연결 할 수 있습니다. 다음 글에서 다룰 내용이기도 합니다.

읽어주셔서 감사합니다.

profile
dog발자

0개의 댓글