2016-11-27 7 views
0

튜토리얼 Functors, Applicatives, And Monads In Pictures 및 해당 JavaScript version을 따라 가면서 내 질문이 떠 올랐습니다.모나드 "unboxing"

텍스트에서 펑터가 컨텍스트의 값을 언 래핑한다고 표시되면 Just 5 ->5 변형이 발생하고 있음을 알았습니다. What does the "Just" syntax mean in Haskell?에 따르면, Maybe 모나드의 "범위에서 정의"됩니다.

제 질문은 전체적인 언 래핑 (unwrapping)에 대해 왜 그렇게 마법입니까? 즉, "범위가 지정된"변수를 자동으로 해제하는 언어 규칙을 갖는 문제는 무엇입니까? 이 작업은 심볼 Just 55에 해당하는 일종의 테이블에서의 조회 일뿐입니다.

제 질문은 자바 스크립트 버전에서 영감을 얻었습니다. Just 5은 프로토 타입 어레이 인스턴스입니다. 그래서 풀리는 것은 로켓 과학이 아닙니다.

"계산 용"유형의 이유인가 "프로그래머 용"이유입니까? 프로그래밍 언어 수준에서 Just 55을 구별하는 이유는 무엇입니까?

답변

7

첫째, 당신이 모나드를 이해할 수 있다고 생각하지 않습니다 유형의 값에서 유형 a의 값을 distinguigh하는 방법과 (하스켈과 같은 언어를 학습하지 않고 예) 타입 시스템과 같은 하스켈을 이해하지 않고 등이다 . 네, 그렇지 않다는 주장을하는 자습서가 많이 있지만, 하스켈을 배우기 전에 많은 책을 읽었습니다. 이해하지 못했습니다. 그래서 충고 : 모나드가 적어도 하스켈을 배워야한다는 것을 이해하고 싶다면.

"프로그래밍 언어 수준에서 Just 55을 구별하는 이유는 무엇입니까?". 안전을 위해. Haskell이 아닌 대부분의 언어에서 null, nil, whatever은 종종 값이 없음을 나타내는 데 사용됩니다. 그러나 값이 없을 수도 있기 때문에 종종 NullPointerExceptions과 같은 결과가 발생합니다.

하스켈에는 null이 없습니다. 따라서 값이 Int이거나 그 밖의 값이면 null이 될 수 없습니다. 당신은 가치가 있음을 보증합니다. 큰! 그러나 때로는 값의 부재를 인코딩하기를 원하거나 필요로합니다. 하스켈에서는 Maybe을 사용합니다. 따라서 Maybe Int 유형은 Just 5 또는 Nothing과 같은 형식 일 수 있습니다.이 방법은 명시 적으로 값이 존재하지 않을 수도 있고 값을 명시 적으로 unwrap해야하기 때문에 실수로 Nothing 일 수 있음을 잊을 수는 없습니다.

Maybe이 Monad 유형 클래스 (Java에 익숙한 경우 유형 클래스는 Java 인터페이스와 비슷 함)를 구현한다는 점을 제외하고는 Monads와 아무런 관련이 없습니다. 그것은 아마도 모나드가 아닐지 모르지만 모나드 일뿐입니다.

2

"unwrap"이란 의미는 컨테이너에 따라 다릅니다. Maybe은 하나의 예일뿐입니다. "포장 해제"는 Maybe 대신에 컨테이너가 [] 일 때 완전히 다른 것을 의미합니다.

언 래핑 (unrapping) 전체에 관한 마법은 추상화입니다. 모나드에서 우리는 컨테이너의 성질을 추상화하는 "언 래핑 (unwrapping)"이라는 개념을 가지고 있습니다. 마찬가지로 데이터 선언을 통해 정의 하스켈의 데이터 유형 생성자에 불과하다 :

data Maybe a = Just a | Nothing 

Just이 값을 가지고 다음은

당신은 Just이 무엇을 의미하는지 물어 ... "마법"얻을 시작 a을 입력하고 Maybe a 유형의 값을 만듭니다. 그것은 하스켈의 모든 Maybe a

4

가능한 예제는 하스켈 유형 Maybe (Maybe Int)입니다. 그 값은 우리가 처음 두 구별 할 수 Just 래퍼없이 어떤 정수 n

에 대한

  • Just Nothing
  • Just (Just n)
  • Nothing
    • 다음과 같은 형식이 될 수 있습니다.

      실제로 옵션 유형 Maybe a의 전체 점은 기존 값 a에 새 값 (Nothing)을 추가하는 것입니다. 그러한 Nothing이 참으로 새로운 값임을 보장하기 위해 다른 값을 Just 안에 넣습니다.

      또한 유형 추정 중에 도움이됩니다. 함수 호출 f 'a'을 보면 Char 유형에서 f이 호출되고 Maybe Char 또는 Maybe (Maybe Char) 유형에서는 호출되지 않음을 알 수 있습니다. typeclass 시스템을 사용하면 f이 각각의 경우에 서로 다른 구현을 가질 수 있습니다 (이는 일부 OOP 언어에서 "오버로드"와 유사합니다).

    5

    나는 이것이 잘못된 방향에서보고 있다고 생각합니다. Monad은 명시 적으로 이 아니며 언 랩핑에 대해서는이 아닙니다. Monad 약 조성입니다.

    유형 의 값을 얻기 위해 a -> m b 유형의 값과 m a 유형의 값을 결합 (반드시 적용 할 필요는 없음) 할 수 있습니다. 확실한 방법은 m a 유형의 값을 a 유형의 값으로 푸는 것입니다. 그러나 매우 적은 수의 Monad 인스턴스가 그런 식으로 작동합니다. 사실, 그런 식으로 작동 할 수있는 유일한 장치는 Identity 형식과 같습니다. 거의 모든 경우에 대해 Monad의 경우 값을 사용 해제 할 수 없습니다.

    Maybe을 고려하십시오. 시작 값이 Nothing 일 때 형식 Maybe a의 값을 a 유형의 값으로 언 래핑하는 것은 불가능합니다. 모나드 구성은 단지 언 래핑하는 것보다 더 재미있는 것을해야합니다.

    []을 고려하십시오. 입력이 그냥 길이 1의리스트가 아니면, [a] 유형의 값을 a 유형의 값으로 전개하는 것은 불가능합니다. 다른 모든 경우에 모나 딕 구성은 언 래핑보다 더 재미있는 작업을 수행하고 있습니다.

    IO을 고려하십시오. getLine :: IO String과 같은 값은 String 값을 포함하지 않습니다. 무언가를 감쌀 수 없기 때문에 풀기가 불가능합니다. IO 값의 모나 딕 (monadic) 구성은 아무 것도 unwrap하지 않습니다.더 복잡한 IO 값으로 IO 값을 결합합니다.

    나는 당신의 관점을 Monad의 의미로 조정하는 것이 가치 있다고 생각합니다. 그것이 단지 언 래핑 (unrapping) 인터페이스라면, 그것은 꽤 쓸모 없게 될 것입니다. 그것은 더 미묘하다. 컴포지션 인터페이스입니다.

    1

    우선, 질문에서 모나드를 제거해야합니다. 그들은이 일을 할 수 없다. 이 기사를 모나드의 관점 중 하나로 취급하십시오. 어쩌면 그것이 여러분에게 적합하지 않을 수도 있습니다. 여러분은 형식 체계에서 haskell의 모나드를 이해하는 것이 거의 이해되지 않을 수도 있습니다.

    질문은 다음과 같이 해석 할 수 있습니다. 암시 적 변환 Just 5 => 5이없는 이유는 무엇입니까? 그러나 대답은 매우 간단합니다. 값 Just 5Maybe Integer 유형이므로이 값은 Nothing이 될 수 있지만이 경우 컴파일러는 무엇을해야합니까? 프로그래머 만이 상황을 해결할 수 있습니다.

    그러나 더 불편한 질문이 있습니다. 유형이 있습니다 (예 : newtype Identity a = Identity a). 그것은 어떤 가치를 감싸는 것입니다. 그렇다면 암시 적 변환이없는 이유는 무엇입니까 Identity a => a?

    간단한 대답은 이것을 실현하려는 시도가 현재 시스템에 존재하는 많은 훌륭한 자질을 가지지 않은 다른 시스템 유형으로 이어질 것이라는 점입니다. 이것에 따르면, 다른 가능성의 이익을 위해 희생 될 수 있습니다.

    2

    제 질문은 전체 언 랩핑에 대해 무엇이 환상적입니까?

    아무 것도 없습니다. 당신은 ... 정의의 (a case 식의 형태로 여기) Maybe에 대한 fmap보다 정확히 동일

    mapMaybe :: (a -> b) -> Maybe a -> Maybe b 
    mapMaybe f mx = case mx of 
        Just x -> Just (f x) 
        _ -> mx 
    

    을 ... 정원 - 다양한 패턴 매칭을 사용할 수 있습니다. Functor 클래스가 추가하는 유일한 것은 - 매우 유용합니다. 실수하지 마십시오 - 매핑 할 수있는 다양한 구조를 포함하는 추가 수준의 추상화입니다.

    프로그래밍 언어 수준에서 Just 55을 구별하는 이유는 무엇입니까? Just 55의 차이보다 의미있는

    유형 사이의 하나입니다 - 예를 들어, Maybe IntInt 사이 x :: Int 인 경우 xInt 값일 수 있습니다. 그러나 mx :: Maybe Int이있는 경우 Int이 누락 될 수 있으므로 (예 : mxNothing 일 수 있음) 이러한 유형의 시스템은 사용자가이 가능성을 인정하고 처리하도록합니다.

    도 참조 : jpath's answer를 (반드시 같은 FunctorMonad 같은 클래스에 연결되지 않은) Maybe의 유용성에 대한 자세한 의견을; Carl's answerFunctorMonad (예 : Maybe 예를 벗어남)과 같은 클래스의 유용성에 대한 자세한 설명은