title: Nested function application
body: <p>It's quite easy to define an operator like</p>
  
  <pre><code>(@) :: [x -&gt; y] -&gt; [x] -&gt; [y]
  </code></pre>
  
  <p>which takes a list of functions and a list of inputs and returns a list of outputs. There are two obvious ways to implement this:</p>
  
  <ol>
  <li>Apply the first function to the first input, the second function to the second input, etc.</li>
  <li>Apply every function to every input.</li>
  </ol>
  
  <p>Either is equally trivial to define. The nice thing about it is that you can now do something like</p>
  
  <pre><code>foo :: X -&gt; Y -&gt; Z -&gt; R
  
  bar :: [X] -&gt; [Y] -&gt; [Z] -&gt; [R]
  bar xs ys zs = [foo] @@ xs @@ ys @@ zs
  </code></pre>
  
  <p>This generalises to an arbitrary number of function arguments.</p>
  
  <hr>
  
  <p>So far so good. Now for the problem: How to I change the type signature for <code>@@</code> such that the type signature for <code>bar</code> becomes</p>
  
  <pre><code>bar :: [X] -&gt; [Y] -&gt; [Z] -&gt; [[[R]]]
  </code></pre>
  
  <p>It's not hard to implement a function with this type; either of these will do it:</p>
  
  <pre><code>bar xs ys zs = map (\ x -&gt; map (\ y -&gt; map (\ z -&gt; foo x y z) zs) ys) zs
  bar xs ys zs = map (\ z -&gt; map (\ y -&gt; map (\ x -&gt; foo x y z) xs) ys) zs
  </code></pre>
  
  <p>I'm not fussy about which result I get. But I can't figure out how to tweak the <code>@@</code> operator to do this.</p>
  
  <hr>
  
  <p>An obvious thing to try is</p>
  
  <pre><code>(@@) :: [x -&gt; y] -&gt; [x] -&gt; [[y]]
  </code></pre>
  
  <p>It's not hard to implement this, but it won't help you. Now you have</p>
  
  <pre><code>[foo] @@ xs :: [[Y -&gt; Z -&gt; R]]
  </code></pre>
  
  <p>which is not a valid input to <code>@@</code>. There's no obvious way to know how many levels of lists to reach through to get to the function; clearly this approach is a dead end.</p>
  
  <p>I've tried several other possible type signatures, but none of them takes me closer to the answer. Can somebody either give me a solution, or explain why none exists?</p>