Applicatives are often presented as a way to lift multi-argument functions into a functor and apply functor values to it. But I wonder if there is some subtle additional power stemming from the fact that it can do so by lifting functions that return a function and applying the function arguments one at a time.
Imagine instead we define an interface based on lifting functions whose argument is a tuple of arguments:
# from Functor
fmap :: (a -> b) -> Fa -> Fb
# from Applicative
pure :: a -> Fa
# combine multiple functor values into a functor of a tuple
tuple1 :: Fa -> F(a)
tuple2 :: Fa -> Fb -> F(a,b)
tuple3 :: Fa -> Fb -> Fc -> F(a,b,c)
(etc ...)
# lift multi-argument functions (that take a tuple as input)
ap_tuple1 :: ((a) -> b) -> F(a) -> Fb
ap_tuple2 :: ((a,b) -> c) -> F(a,b) -> Fc
ap_tuple3 :: ((a,b,c) -> d) -> F(a,b,c) -> Fd
(etc ..)
Assume we had the corresponding tuple function defined for every sized tuple we may encounter. Would this interface be equally as powerful as the Applicative interface, given it allows for lifting/applying-to multi-argument functions BUT doesn't allow for lifting/applying-to functions that return a function? Obviously one can curry functions that take a tuple as an argument so they can be lifted in an applicative and one can uncurry functions that return a function in order to lift them into hypothetical implementation above. But to my mind there is a subtle difference in power. Is there any difference? (Assuming the question even makes sense)