Как правило, кортежи не образуют монады, но оператор >>=
работает только с Monad
.
Что вы можете сделать, так это просто составить, используя вместо этого $
:
*Q62478798> (\(a,b) -> pop b) $ pop [1, 2, 3]
(2,[3])
Если вы предпочитаете композицию слева направо, вы можете использовать оператор &
из Data.Function
:
*Q62478798 Data.Function> pop [1,2,3] & (\(a,b) -> pop b)
(2,[3])
С другой стороны, кортежи do образуют монады, если первый элемент образует моноид, как видно из этого примера:
Monoid a => Monad ((,) a)
Что вы могли бы сделать, так это сначала ослабить тип pop
:
pop :: [a] -> (a, [a])
pop (x:xs) = (x,xs)
Это позволяет вам pop
из списка любого типа, включая списки моноидальных типов, например:
*Q62478798 Data.Monoid> pop $ fmap Sum [1,2,3]
(Sum {getSum = 1},[Sum {getSum = 2},Sum {getSum = 3}])
Теперь вы можете составлять с Оператор >>=
:
*Q62478798 Data.Monoid> (pop $ fmap Sum [1,2,3]) >>= (\xs -> pop xs)
(Sum {getSum = 3},[Sum {getSum = 3}])
или, сокращение эта:
*Q62478798 Data.Monoid> (pop $ fmap Sum [1,2,3]) >>= pop
(Sum {getSum = 3},[Sum {getSum = 3}])
Эта комбинация композиции справа налево и слева направо совершенно нечитаема, так что вы можете использовать &
или =<<
:
*Q62478798 Data.Monoid> pop =<< (pop $ fmap Sum [1,2,3])
(Sum {getSum = 3},[Sum {getSum = 3}])
Я не знаю, зачем вы это делаете, но вы можете.