title: zipWith for trees in Haskell
body: <p>I am learning Haskell using The Haskell School of Expression: Learning Functional Programming through Multimedia and I am unsure how to go about solving this exercise. </p>
  
  <blockquote>
    <p>Using the definition of trees given by </p>
  
  <pre><code>data Tree a = Node (Tree a) (Tree a) | Leaf a
  </code></pre>
    
    <p>Define tree versions of the list functions <code>zip</code> and <code>zipWith</code>. There
    will be cases at the leaves or where trees are of different shapes
    where you’ll have to make design decisions. Try to make your decisions
    as elegant as possible.</p>
  </blockquote>
  
  <p>For <code>zip</code> I have this but I am unsure if it is "elegant"</p>
  
  <pre class="lang-haskell prettyprint-override"><code>zipTree :: Tree a -&gt; Tree b -&gt; Tree (a,b)
  zipTree (Leaf a)     (Leaf b)     = Leaf (a,b)
  zipTree (Node l1 r1) (Node l2 r2) = 
    let l = zipTree l1 l2
        r = zipTree r1 r2 
    in Node l r 
  
  -- Problems...
  zipTree (Node _ _)  (Leaf _)   = Node undefined undefined
  zipTree (Leaf _)    (Node _ _) = Node undefined undefined
  </code></pre>
  
  <p>And I am unsure how to adapt it to have <code>zipWith</code> functionality although I do know a elegant definition of zipWith.</p>
  
  <pre class="lang-haskell prettyprint-override"><code>zipWith :: (a -&gt; b -&gt; c) -&gt; [a] -&gt; [b] -&gt; [c]
  zipWith f (x:xs) (y:ys) = f x y : zipWith f xs ys
  zipWith _ _ _ = []
  </code></pre>