2017-02-16 4 views
12

두 개의 모나드가있는 경우 mn이고, n은 통과 할 수 있습니다. 모나드는 m-over- n 모나드입니까? 당연히트래버스가 가능한 임의의 모나드의 구성이 항상 모나드입니까?

import Control.Monad 
import Data.Functor.Compose 

prebind :: (Monad m, Monad n) => 
     m (n a) -> (a -> m (n b)) -> m (n (m (n b))) 
mnx `prebind` f = do nx <- mnx 
        return $ do x <- nx 
           return $ f x 

instance (Monad m, Monad n, Traversable n) => Monad (Compose m n) where 
    return = Compose . return . return 
    Compose mnmnx >>= f = Compose $ do nmnx <- mnmnx `prebind` (getCompose . f) 
            nnx <- sequence nmnx 
            return $ join nnx 

,이 유형 검사, 그리고 내가 확인 몇 가지 경우에 대한 작품을 믿는다 (목록을 통해 독자를, 국가 목록 이상) - :

더 공식적으로, 여기에 내가 생각하고있는거야 에서와 같이 구성된 '모나드'는 모나드 법칙을 충족시킵니다. 그러나이 모 바브가 통과 할 수있는 모나드를 겹겹이 만드는 방법은 일반 인 경우 확실하지 않습니다.

+5

[여기] (http://www.math.mcgill.ca/barr/papers/ttt.pdf)는 범주 이론의 관점에서이 주제를 다루는 훌륭한 책입니다 (특히, p257 "Distributive 법칙 "이라고 부르며, 범주 이론을 이미 알고있는 누군가의 관점에서) 상대적으로 *를 제공한다. 'M'과 'N'이 모나드이면 모나드가됩니다. [Here] (http://stackoverflow.com/questions/29453915/composing-monads-v-applicative-functors)는 주어진 코드에 약간의 변형을 나타내는 또 다른 질문입니다. 아마도 더 유용한 출발점이 될 것입니다 . – user2407038

+2

겁탈 자 : 그렇습니다. – user2407038

+0

롤, 고마워요! 나는 그 스레드를 오래 전에 읽지 못했지만, 긍정적 인 대답을 담고있는 [이 주석] (http://stackoverflow.com/questions/29453915/composing-monads-v-applicative-functors#comment47075703_29454112)을 놓쳤습니다. –

답변

3

아니요, 항상 모나스트가 아닙니다. 두 모나드의 모나드 연산과 분배 법 sequence :: n (m a) -> m (n a)에 대한 추가 호환성 조건이 필요합니다 (예 : Wikipedia에 설명되어 있음). ] 내지 [X]> SX 전송 X -

Your previous question

부와, X가 호환성 조건, 즉

S = m = [] 충족되지 않는 일례를 준다 TX = X × X이고, X -> TX는 (x, x)로 x를 전송한다.

은 Wikipedia 페이지의 우측 하단 도면 합성 S 때문에, 통근 않는다 -> TS -> ST가 xs :: [a](xs,xs)에 다음 xs로부터 인출 모든 쌍의 직교 제품 보낸다 오른쪽지도 S -> ST는 xsx에 대한 (x,x) 쌍으로 만 구성된 "대각선"에 xs을 보냅니다. 그것은 제안 된 모나드가 단위 법칙 중 하나를 만족시키지 못하게하는 동일한 문제입니다.

+0

나는 분명히 뭔가 빠져 있다고 생각합니다. '[] '는 트래버스 가능하지만'(->) r'은 그렇지 않기 때문에 위의 방법은 List-over-Reader 모나드가 아닌 Reader-Over-List (또는 Set) 모나드를 파생시킬 수있는 방법을 제공합니다 , 그것은 나의 이전 질문이 물었던 것이다. –

+0

죄송합니다. 이제'(->) Bool'이 실제로 통과 할 수있는 이유가 있습니다. '(->) r'은 유한 한'r' (당신이 링크 된 질문에 암시 된 라인을 따라)에 대해 트래버스 가능합니까? –

+1

'(->) Bool' 또는 임의의 유한 타입'r'에 대한'(->) r'은'| r |'- tuple과 동등하므로 탐색이 가능합니다. –

3

Reid Barton's general answer과 구체적 질문 사이의 연결을 좀 더 명확하게하기 위해 몇 가지 추가 설명이 있습니다. 이 경우

, 그것은 정말 join의 관점에서 Monad 인스턴스를 해결하기 위해 갚는다 :

join' :: m (n (m (n b))) -> m (n b) 
join' = fmap join . join . fmap sequence 

적절한 장소에서 compose/getCompose를 재 도입하고 m >>= f = join (fmap f m)를 사용하면이 실제로 있는지 확인할 수 있습니다 귀하의 정의와 같습니다 (귀하의 prebind은 해당 방정식에서 fmap f에 해당합니다).

이 정의는 다이어그램 으로 법을 확인하는 것을 편안하게합니다.

 

    MT id  MT id MT id MT 
    ---->  ---->  ----> 
rT2 | | rT1 | | rT1 | | id 
rM3 V V rM3 V V  V V 
    ---->  ---->  ----> 
MTMT sM2 MMTT jM2 MTT jT0 MT 

전체 사각형이 모나드 법입니다 : 여기 join . return = id(fmap join . join . fmap sequence) . (return . return) = id 하나입니다

 
M id M 
    ---->  
rM1 | | id 
    V V 
    ---->  
MM jM0 M 

반드시 사각형에서 두 가지 동일한 부분을 무시하고, 우리가 볼 수있는 두 개의 오른쪽 그 사각형은 동일한 법에 해당합니다. (물론이 "사각형"과 "사각형"이라고 부르는 것은 바보입니다. id면을 모두 가지고 있지만 제한된 ASCII 아트 기술에 더 잘 맞습니다.) 첫 번째 광장,하지만 ... 리드 바튼 언급 위키 피 디아 페이지의 오른쪽 아래 그림은 sequence . return = fmap return

 
M id M 
    ---->  
rT1 | | rT0 
    V V 
    ---->  
TM sM1 MT 

을 금액 ... 그리고 그것은 즉, 보유하고 주어진로 리드 바튼의 아니다 대답을 보여줍니다.

동일한 전략을 join . fmap return = id 법칙에 적용하면 오른쪽 상단 다이어그램 sequence . fmap return = return이 표시됩니다. 그러나 그 자체만으로는 문제가되지 않습니다. 신원 확인법은 Traversable입니다. 마지막으로 join . fmap join = join . join 법으로 동일한 작업을 수행하면 다른 두 다이어그램, 즉 sequence . fmap join = join . fmap sequence . sequencesequence . join = join . sequence . fmap sequence이 생성됩니다.


각주 : 속기에 대한

  1. 설명 : rreturn이다, ssequencej이다는 join이다. 기능 약어가 붙은 대문자와 숫자는 관련된 모나드와 그 위치를 명확하게 해준다. 으로 끝난다. s의 경우에는 이 처음으로 인 것을 의미한다. 우리는 외부 레이어가 항상 T임을 알고 있습니다. 레이어는 0부터 시작하여 아래에서 위로 번호가 지정됩니다. 첫 번째 함수 아래에 두 번째 함수의 속기를 쓰면 구성이 표시됩니다.