Suppose I have a value of type Monad m => (m a, m a)
, and I want to "sequence" the pair to create a value of type Monad m => m (a, a)
that combines the monadic context of the two values in the same way the "sequence" function does. Is there some standard function or standard way of doing this? And does this operation even make sense?
ghci> import Control.Lens
ghci> sequenceOf both (getLine, getLine)
Apples
Bananas
("Apples","Bananas")
There wouldn't be a single function for all the different tuple types, since it wouldn't have a single type.
You could define a family of functions like:
ts0 = return
ts2 = uncurry $ liftM2 (,)
ts3 = uncurr3 $ liftM3 (,,)
{- ... -}
uncurr3 f (x, y, z) = f x y z
Of course, sequence in general is better applied to applicatives instead of monads, which is why it is part of the Traversable typeclass. It would be possible to make homogenous tuples [(a,a,a) but not (a,b,a)] an instance of MonoTraversable, I believe.
You should also see another answer which indicates there is already a library containing this family of functions.
The tuple package has Data.Tuple.Sequence.sequenceT
which is overloaded for up to 32-tuples.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With