2016-07-16 15 views
6

내가 알아챈 한 가지는 Tuple에는 Monad 인스턴스가 없습니다. 이미 매우 크게 우리가 Monad 인스턴스가 될 수 있습니다 어떤 제한튜플에 Monad 인스턴스가없는 이유는 무엇입니까?

instance Monoid a => Applicative ((,) a) 

:

튜플 그러나 Applicative 인스턴스가 않습니다.

instance Monoid a => Monad ((,) a) 

join :: Monad m => m (m a) -> m a 

join :: Monoid a => (a, (a, b)) -> (a, b) 

우리는 또한 모나드 법률 볼 수 있습니다 :

가입을 위해 우리가 얻을 것 유형 서명을 볼 수 있습니다

join $ f <$> pure x == f x 
join $ f <$> (mempty, x) == f x 
join (mempty, f x) == f x 
join (mempty, (a, b)) == (a, b) 

join $ pure <$> x = x 
join $ pure <$> (a, b) = (a, b) 
join (a, (mempty, b)) = (a, b) 

우리가 알고있는이 시점에서이 점에서 memptyx을 결합 어느 쪽이든 경우 x이됩니다. 그리고 우리가 가지고있는 유일한 타입 정보는 x입니다. Monoid입니다. 그래서 기본적으로 두 구현은 다음과 같습니다

join (a, (b, x)) = (a <> b, x) 

과 :

join (a, (b, x)) = (b <> a, x) 

그리고 그 차종 ap<*> 동일하지의 두 번째입니다.

그래서 지금 우리는 ((,) a)의 유일한 유효 Monad 인스턴스 인 것을 알고 :

instance Monoid a => Monad ((,) a) where 
    (a, c) >>= f = let (b, c') = f c in (a <> b, c') 

은 왜 현재의 경우가 아니다?

+6

'ghci'는'ghci'가'인스턴스 Monoid a => 모나드 ((,) a) - 'GHC.Base''에 정의 됨 – Michael

+0

으로 추측됩니다. 야생의 추측 : 충분히 장군? 'Set'가 하나도 가지고 있지 않은 이유는 ... – ThreeFx

+1

모나드 법칙을 만족하는 인스턴스가 존재할 수 없기 때문에'Set'은 모나드 인스턴스를 갖지 않습니다. 제안 된 인스턴스'((,) a)는 법을 준수하고 있으며 법을 준수 할 수있는 유일한 인스턴스라고 생각합니다. 따라서 그것을 만드는 것이 합리적입니다. – amalloy

답변

1

이 질문에 대한 답은 단지 ghc-8.0.1을 사용해야한다는 것입니다. TupleMonad 인스턴스를 제공합니다. 이것을 지적 해 주신 @Michael에게 감사드립니다.

+1

'8.1'은 아직 출력되지 않았습니다. 그는 8.0.1을 의미했다. 인스턴스는 [여기] (https://hackage.haskell.org/package/base-4.9.0.0/docs/Control-Monad.html#control.i:ic:Monad:Monad:25)에서 찾을 수 있습니다. – crockeea

+0

@ Eric ah ok, 감사합니다! – semicolon

관련 문제