Ответ 1
Control.Arrow
не уделяет много внимания функциям более высокой степени. То, что вам действительно нужно, это функция foo :: (a -> a' -> a'') -> (b -> b' -> b'') -> (a,b) -> (a',b') -> (a'',b'')
, аналог (***)
для функций arity 2. В Data.Biapplicative(из бифунтера пакета) есть такая функция, которая имеет несколько более общую подпись biliftA2 :: Biapplicative w => (a -> b -> c) -> (d -> e -> f) -> w a d -> w b e -> w c f
. Поскольку существует биапликативный экземпляр для двухэлементных кортежей, это все, что вам нужно.
Единственная жалоба, которую я вижу против вашего кода, так это то, что кармирование лямбда неочевидно; Я бы предпочел более явный \(a,b) (a',b') -> (lfn a a', rfn b b')
.
Редактирование заметок: я пришел к выводу, что необходимой функции не существует, и предложил ее определить; вызванный комментариями Карла, я нашел в Biapplicative (более общая подпись типа помешала Hoogle найти его под моей предложенной сигнатурой).