2012-01-26 8 views
11

두 개의 모나드 인 mm'이 있다고 가정 해 보겠습니다. 이제, 제품 m x m'과 비슷한 것을 만들 수있는 방법이 있나요, 우리는 변수를 가질"두 모나드의 제품"효과를 얻는 방법?

-- in real problems, the restriction is some subclass MyMonad, so don't worry 
-- if it's the case here that mx and f must essentially be pure. 
mx :: Monad m'' => m'' a 
f :: Monad m'' => a -> m'' b 

를 생각? 나는 이것이 Arrows에서 가능하다는 것을 알고 있지만, 특히 mx >>= f이해야 할 일을 쓰려고 할 때, 더 복잡해 보인다 (불가능할 것 같은)? 내가 동형 수 (mx >>= f) :: ProdM를 원 mx에서 어떤 값이 f에 전달할

(ProdM mx mx') >>= f 
     {- result 1 -} = mx >>= f 
     {- result 2 -} = mx' >>= f 

data ProdM a = ProdM (m a) (m' a) 
instance Monad ProdM where 
    return x = ProdM (return x) (return x) 

을 정의하고이를 보려면하지만 우리는 mx >>= f를 정의 할 때 지금, 그것은 분명하지 않다 ((mx >>= f) :: m) x ((mx >>= f) :: m').

답변

18

예,이 유형은 모나드입니다. 열쇠는 을 모두 결과를 f에 전달하고 결과에서 일치하는 필드 만 유지하는 것입니다. 즉, 우리는 mx의 결과를 전달한 결과에서 첫 번째 요소를 유지하고 mx'의 결과를 전달한 결과에서 두 번째 요소를 유지합니다. 인스턴스는 다음과 같습니다

instance (Monad m, Monad m') => Monad (ProdM m m') where 
    return a = ProdM (return a) (return a) 
    ProdM mx mx' >>= f = ProdM (mx >>= fstProd . f) (mx' >>= sndProd . f) 
    where fstProd (ProdM my _) = my 
      sndProd (ProdM _ my') = my' 

ProdM 이름 Product 아래 monad-products 패키지로 제공된다.

+1

ehird의 해법은 또한 동작 f가 두 번 실행된다는 것을 의미합니다. 모나드 m과 m '이 부작용을 관찰 할 수 있다면 이것은 예상치 못한 결과 일 수 있습니다. – Lemming

관련 문제