generalize map2 function