Фактически, единственный правильный экземпляр монады Pair
выглядит следующим образом.
instance Monad Pair where
m >>= f = joinPair (f <$> m)
joinPair :: Pair (Pair a) -> Pair a
joinPair (Pair (Pair x _) (Pair _ y)) = Pair x y
Причина, по которой это правильный экземпляр монады, заключается в том, что Pair
является представимым функтором .
instance Representable Pair where
type Rep Pair = Bool
index (Pair x _) False = x
index (Pair _ y) True = y
tabulate f = Pair (f False) (f True)
Оказывается, для каждого представимого функтора (>>=)
эквивалентна следующей bindRep
функции.
bindRep :: Representable f => f a -> (a -> f b) -> f b
bindRep m f = tabulate (\a -> index (f (index m a)) a)
Если мы специализируемся на bindRep
функция к Pair
мы получаем следующее.
bindRep :: Pair a -> (a -> Pair b) -> Pair b
bindRep (Pair x y) f = tabulate (\a -> index (f (index (Pair x y) a)) a)
= Pair (index (f x) False) (index (f y) True)
-- |_________________| |________________|
-- | |
-- (1st elem of f x) (2nd elem of f y)
Следующая запись в блоге Адельберта Чанга объясняет это лучше. Рассуждение с представимыми функторами .