2010-11-20 4 views
2
guard :: (MonadPlus m) => Bool -> m() 
guard True = return() 
guard False = mzero 

Prelude Control.Monad> :t mzero 
mzero :: (MonadPlus m) => m a 

guard의 잘못된 분기에서 mzero의 유형은 m a이지만 guard의 리턴 유형은 m()로 지정되었습니다. 따라서 나는 왜 컴파일러가 이것에 대해 불평하지 않는지 이해하지 못한다.'m'vs 'm'() '가드 있음

mzeroMaybe Int로 형식화 된 값을 반환하면 Maybe()과 다르다는 것을 의미합니다. 맞습니까?

답변

6

m am()의 상위 집합이므로 컴파일러에서 불평하지 않습니다.

+0

'mzero'는 '어쩌면 Int'와 같은 것을 반환 할 수 있습니까? 나는 Maybe()와 다르다고 생각한다. – aXqd

+1

@aXqd : Maybe 모나드의 경우,'mzero = Nothing'은'a'에 대해 선호하는 타입이 없다. 만약 당신이 실제로'어쩌면 Int '에'Nothing'을 던지면'Maybe()'와는 다릅니다. 그러나, 타입은'아마도'아마도 가능한'a'가 아니라'아마도 어쩌면 Int'가 될 것이므로'Maybe()'가 유효합니다. – kennytm

+0

@KennyTM 답장을 보내 주셔서 감사합니다. 예, 나쁜 예를 사용할 수 있습니다. 그러나 사용자 정의 유형 - 'MyType'을 작성한 다음 'Monad'및 'MonadPlus'의 인스턴스로 만듭니다. 그러면 'mzero'가 'MyType Int'를 반환 할 수 있습니다. 사실, 'mzero'에 의해 반환 될 결과가 'm()'이 아닌 경우 컴파일러는이 문제에 대해 불평해야한다고 생각합니다. 'mzero'의 유형과 'guard'의 리턴 유형이 서로 일치하지 않기 때문에. 나는이 결론에 내가 틀렸다는 것을 알고있다. 문제가 어디 있는지 모르겠습니다. : P – aXqd

0

mzero :: (MonadPlus m) => m a의 유형 forall (a :: *) (m :: * -> *). MonadPlus m => m a 짧은 손의 비트 mMonadPlus typeclass의 인스턴스인지 단지 제한이 만족되면 mmzero 수, a를 입력 종류별 생성자 임의 선택 의미이며 그 타입에 있으십시오.

마찬가지로 guard의 유형은 forall (m :: * -> *). MonadPlus m => Bool -> m()입니다. guard False = mzero에서 오른쪽에 mzero의 유형은 m의 적절한 선택에 대해 m()이어야합니다. a()으로 선택하고 m을 요청한 모나드로 사용하면 mzero의 유형 자체가 m()이되며 정확히 guard이 반환해야합니다.

+0

이전에는 '가드'의 유형이었습니다. 이제 그것은'guard :: Alternative f => Bool -> f()'입니다. 나는 새로운 대답이 새로운 유형을 반영해야한다고 생각한다. – dfeuer

+0

그러나 내 편집은 수정 일뿐입니다. – dfeuer

관련 문제