user3416536
user3416536

Reputation: 1469

Haskell: how to map a function over an arbitrary tuple of monads

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

Answers (1)

AJF
AJF

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

Related Questions