2017-02-04 8 views
5

현재 Alternative/MonadPlus의 안경은 wikibooks입니다. 차이점을 잘 설명합니다. 그러나, 난처한 부분은 guard 함수입니다.이 함수는 계산을 "단락"하는 데 사용됩니다. (맞습니까?)MonadPlus 제약 조건으로`guard`가 정의되지 않은 이유는 무엇입니까?

Control.Monad에 정의되어 있지만 기능이 guard 인 경우 Alternative 제약 조건이 있습니다 (link).

guard   :: (Alternative f) => Bool -> f() 
guard True  = pure() 
guard False  = empty 

그러나 위의 기사 만 MonadPlus가 왼쪽 제로 오른쪽 제로 법 (따라서 강한 주장을) 시행 할 필요가 있음을 언급하고있다.

mzero >>= f = mzero -- left zero 
m >> mzero = mzero -- right zero 

guard 기능의 목적을 감안할 때, 그것은 MonadPlus 제약 조건으로 정의되어서는 안된다? guard가 계산을 "단락"한다고 가정 할 때 더 강력한 법칙이 필요하지 않습니까? 특정 디자인 선택의 이유에 대해 궁금합니다.

p.s : "단락"이라는 단어 이외의 "선행 계산 취소"동작을 설명하는 더 좋은 방법은 무엇인지 모르겠습니다.

+2

'MonadPlus'는'Alternative'보다 강력하고'guard '를 쓰는'MonadPlus'는 필요 없습니다 - 대체 형을 가진 타입이 가장 일반적인 타입, 즉 유추 된 타입입니다. 왜 더 강한 유형을 부여할까요? (wikibooks 페이지는 AMP 이후 구식이므로 ghc 8 이상은 기억하지 못합니다.) – user2407038

+0

@ user2407038 가드가해야 할 경우 더 강력한 법칙 (0, 오른쪽 영점)이 필요하지 않습니다. "단락"? – zeronone

+0

'Applicative' 컨텍스트에서'short circuiting '을 얻습니다 :'guard False *> x = empty'와'guard True *> x = x'; 'Monad '에서'Applicative '가 작동하는 모든 것이 모나드에서 작동하는 것과 똑같은 자연스러운 방식으로'Monad '에서도 작동합니다. – user2407038

답변

0

guard은 함수 정의를 위해 모나드 연산을 수행 할 필요가 없기 때문에 Applicative 제약 조건을 갖습니다.

그것의 정의합니다 (Hackage source에서 복사)한다 : 그 대신 AlternativeMonadPlus

guard   :: (Alternative f) => Bool -> f() 
guard True  = pure() 
guard False  = empty 

을 지정했다면, 그것은 아무것도 얻은 않을 것이다. MonadPlusAlternative의 하위 클래스이므로 모든 MonadPlus 인스턴스는 guard을 사용할 수 있지만 모두가 Alternatives을 사용할 수있는 것은 아닙니다.

은 (제외 Alternatives매우 몇 가지 경우가있을 것입니다 만 - 두 경우는 here들이 왼쪽 분배 규칙을 만족하지 않는 경우에도 MonadPlus의 인스턴스를 언급했다.) 일반적으로

, 그것의 의도 한 용도가 더 구체적 일지라도 기능을 작성하는 데 필요한 최소한의 제한을 준수하는 것이 좋습니다. 이렇게해서는 안되는 것은 제외되어서는 안되며, 유형이 작동 할 수 있지만 모나드가 아닌 사람들로부터의 불만은 없습니다.

우연히 클릭하면 Hoogle search resultsMonadPlus 제한이 잘못 표시됩니다. 그러나 링크를 클릭해도 정확합니다.

+0

AFAIK 함수는 MonadPlus 제약으로 정의되었고, 후자는 Applicative로 변경되었습니다. – zeronone