2017-03-02 18 views
11

아마 모나드 유형 (연쇄, 반환 값에 따라 조건부 함수를 적용하고 연쇄 함수가 실패한 오류 메시지 등을 반환)을 중심으로 놀고있었습니다. 그래서 저는 모나드를 사용하여 우리가 할 수있는 것과 같고 더 많은 일을 성취 할 수있는 것처럼 보입니다. 그래서 제 질문은 그것들 사이의 실제적 또는 개념적 차이점이 어디에 있습니까?우리는 모나드에 모나드가 필요한 이유는 무엇입니까

+0

나는 속은 것이 아니라고 기절. 좋은 질문입니다. –

답변

10

물론 Maybe aEither Unit a과 동형입니다. 문제는 그들은 종종 의미 다른 것을 표시하기 위해 사용되는 즉, NoSuchElementExceptionnull를 반환하고 던지는 사이의 차이 같은 비트 :

  • Nothing/None는 "기대"하면서, 뭔가 빠진
  • Left e을 의미 어떤 이유로 든 그것을 얻는 데있어서의 오류를 나타냅니다.

    우리가 누락 된 값 (A DB NULL)의 가능성과 관련하여 오류를 모두 표현
    query :: Either DBError (Maybe String) 
    

    의 DBMS :

우리는 심지어 같은 것으로 두 가지를 결합 할 수도 말했다 , 또는 무엇이든지 (더 좋은 디자인은 없다는 말은 아니지만, 요점을 얻는다).

때때로 테두리가 유동적입니다. saveHead :: [a] -> Maybe a의 경우, 오류의 예상되는 가능성은 함수의 의도에 따라 인코딩되는 반면, saveDivideFloat -> Float -> Either FPError Float 또는 Float -> Float -> Maybe Float으로 인코딩 될 수 있습니다 (사용 사례에 따라 다름) .

의심, 가장 좋은 방법은 (주관적인 점을 의미 인코딩 사용자 지정 결과 ADT (같은 data QueryResult = Success String | Null | Failure DBError)를 사용하고,이 "전통적으로 예상"되는 간단한 경우에 Maybe을 선호하는 아마 경우, 이는 그러나 것 경험이 생기면 대부분 OK입니다.)

5

@ phg의 답변은 훌륭합니다. 내가 그들을 배울 때 나는 나를 위해 그것을 명확까지 도움이 뭔가 차임됩니다

  • Maybe 하나 (값) 또는 없음이다 - 즉, 당신이 값이 있거나 아무것도
  • Either는이다 논리적 분리가 있지만 항상 하나 이상의 (값)을가집니다. 즉, 또는 중 하나를 가지지 만 둘 다를 가질 수는 없습니다.

Maybe은 가치가 있거나 가치가 없을 수도 있습니다 (예 : 목록의 항목 찾기). 목록에 포함되어 있으면 (Maybe x)을 얻습니다. 그렇지 않은 경우 Nothing

Either은 코드의 분기 표현을 완벽하게 나타냅니다. 어느 방향 으로든 갈 것입니다. Left 또는 Right. 우리는 그것을 기억하기 위해 니모닉을 사용합니다 : (은 올바른)입니다. Left입니다. 웨이 (오류)입니다. 이것은 당연히 사용하는 것이 아니라 가장 일반적인 것입니다.

처음에는 미묘한 차이가있을 수 있지만 실제로는 매우 다른 것들에 적합하다는 것을 알고 있습니다.

+1

논리적 분리를 언급하면 ​​+ 1이됩니다. 이것은 FP를 처음 사용하는 누군가에게 매우 접근하기 쉬운 대답입니다. –

+0

감사합니다. 귀하의 의견은 많은 것을 의미합니다^_ ^ – naomik

1

글쎄, 모든 제품 유형이에 의해 단지 2-tuples 및 모든 비 재귀 적 합계 유형으로 나타낼 수 있다고 말하면 극단에이를 넣을 수 있습니다. 재귀 유형을 추가로 나타내려면 고정 점 유형이 필요합니다.

예를 들어, (a, (b, (c,d))) 또는 (((a,b), c), d)을 쓸 수있는 경우에 4- 튜플 (a,b,c,d)을 사용하는 이유는 무엇입니까?

또는 다음의 경우에도 목록이있는 이유는 무엇입니까?

data Y f = Y (f (Y f)) 

type List a = Y ((,) (Either() a)) 


nil = Y (Left(), undefined) 

cons a as = Y (Right a, as) 

infixr 4 cons 

numbers = 1 `cons` 2 `cons` 3 `cons` nil 

-- this is like foldl 

reduce f z (Y (Left(), _)) = z 
reduce f z (Y (Right x, xs)) = reduce f (f z x) xs 


total = reduce (+) 0 numbers