Reputation: 1469
Is it possible to construct a function that will map of a tuple of monads of arbitrary arity?
E.g.,
f :: (m a -> m [a]) -> (m x, m y) -> (m [x], m [y])
(but for arbitrary arity). This similar question, has a number of promising suggestions; e.g., lens' each
or over both
, but each seem to require a tuple of homogenous types: I want to use a tuple of homogenous monads with differing inner types.
Upvotes: 2
Views: 316
Reputation: 11913
It's not possible in the way that you're saying.
In your type signature, the initial function can only take an m a
, but you expect to pass it an m x
and an m y
, so the types don't match.
It's certainly possible to do it with rankNTypes
enabled:
{-# LANGUAGE rankNTypes #-}
f :: Monad m => (forall a. m a -> m [a]) -> (m x, m y) -> (m [x], m [y])
f fun (x, y) = (fun x, fun y)
This is because forall a.
inside the brackets forces it to be polymorphic, rather than just for a type a
.
What you're probably wanting is something like this:
f :: Monad m => (a -> m b) -> (m a, m a) -> (m b, m b)
or even
f :: Monad m => (a -> m c) -> (b -> m d) -> (m a, m b) -> (m c, m d)
Note that I changed the function type from m a -> m b
to a -> m b
because that allows us to sequence monadic actions, rather than transform the monad, which makes more sense when we want to manipulate them.
Upvotes: 4