Implement a zipwith function zipwith is a functional construct that takes three arguments: one binary function and two lists of the same length, and returns a single list where each element is constructed by applying the binary function to each pair of elements from the two lists:
zipwith (a+b) [1,2,3] [4,5,6] = [5,7,9]

You are to take a black-box function which takes exactly two arguments and two non-empty arrays of the same length consisting of positive integers, and output the result of applying zipwith to this function and arrays.
For the sake of simplicity, you can assume that the black-box function will always input and output integers within your language's integer domain.
If your answer consists solely of a builtin which does this (for example Haskell's zipWith), please edit into this Community Wiki answer. You may input and output in any convenient method.
This is code-golf so the shortest code in bytes wins
Test Cases
function, array, array -&gt; output
a = b, [1, 2, 3], [3, 2, 1] -&gt; [0, 1, 0]
a - b, [8, 3], [3, 8] -&gt; [5, -5]
a² + b/2, [6, 8, 1, 3], [5, 3, 6, 2] -&gt; [38, 65, 4, 10]
a × φ(b), [4, 2, 5, 8, 3], [7, 6, 10, 2, 1] -&gt; [24, 4, 20, 8, 3]

The third test case uses integer (floor) division. The fourth uses the Euler Totient function
Haskell, 22 bytes

(.zip).(.).map.uncurry

Try it online!
Not particularly interesting, just a reimplementation of zipWith converted to pointfree form:
\f x y -&gt; map (uncurry f) (zip x y)
\f x -&gt; map (uncurry f) . zip x
\f x -&gt; (map (uncurry f) .) zip x
\f -&gt; (map (uncurry f) .) . zip
\f -&gt; (. zip) (map (uncurry f) .)
\f -&gt; (. zip) ((.) (map (uncurry f)))
\f -&gt; (. zip) ((.) ((map . uncurry) f))
\f -&gt; (. zip) ((.) . (map . uncurry) $ f)
\f -&gt; (. zip) . ((.) . (map . uncurry)) $ f
(. zip) . ((.) . (map . uncurry))