I think traverse analogues to the map functions in Relude.Extra.Tuple would be useful:
traverseToFst :: Functor t => (a -> t b) -> a -> t (b, a)
traverseToFst f a = flip (,) a <$> f a
traverseToSnd :: Functor t => (a -> t b) -> a -> t (a, b)
traverseToSnd f a = (,) a <$> f a
traverseBoth :: Applicative t => (a -> t b) -> (a, a) -> t (b, b)
traverseBoth f (a1, a2) = (,) <$> f a1 <*> f a2
(No analogue of dupe, at least for now, because there'd be ambiguity over whether it worked like \a -> join (,) <$> a or like \a -> (,) <$> a <*> a, and I'm not sure which would be better.)
The use case that inspired this was a function (FilePath -> IO (FilePath, String)) that takes a filename, and returns a pair of the name and the contents. With this proposal, such a function would simply be traverseToSnd readFile.
If this idea is acceptable, I'll make a PR that adds it along with hlint rules and tests.
I think
traverseanalogues to themapfunctions inRelude.Extra.Tuplewould be useful:(No analogue of
dupe, at least for now, because there'd be ambiguity over whether it worked like\a -> join (,) <$> aor like\a -> (,) <$> a <*> a, and I'm not sure which would be better.)The use case that inspired this was a function (
FilePath -> IO (FilePath, String)) that takes a filename, and returns a pair of the name and the contents. With this proposal, such a function would simply betraverseToSnd readFile.If this idea is acceptable, I'll make a PR that adds it along with hlint rules and tests.