I second Ryan&#39;s recommendation of using unamb [1,2,3] to give you unbiased (symmetric) laziness.<br><br>The zip definition could also be written as<br><br>&nbsp;&nbsp;&nbsp; zip xs@(x:xs&#39;) ys@(y:ys&#39;) =<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assuming (xs == []) [] `unamb`<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assuming (ys == []) [] `unamb`<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (x,y) : zip xs&#39; ys&#39;<br><br>The &#39;assuming&#39; function yields a value if a condition is true and otherwise is bottom:<br><br>&nbsp;&nbsp;&nbsp; assuming :: Bool -&gt; a -&gt; a<br>
&nbsp;&nbsp;&nbsp; assuming True&nbsp; a = a<br>&nbsp;&nbsp;&nbsp; assuming False _ = undefined<br><br>This zip definition is a special case of the annihilator pattern, so<br><br>&nbsp;&nbsp;&nbsp; zip = parAnnihilator (\ (x:xs&#39;) (y:ys&#39;) -&gt; (x,y) : zip xs&#39; ys&#39;) []<br>
<br>where &#39;parAnnihilator&#39; is defined in Data.Unamb (along with other goodies) as follows:<br><br>&nbsp;&nbsp;&nbsp; parAnnihilator :: Eq a =&gt; (a -&gt; a -&gt; a) -&gt; a -&gt; (a -&gt; a -&gt; a)<br>&nbsp;&nbsp;&nbsp; parAnnihilator op ann x y =<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assuming (x == ann) ann `unamb`<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assuming (y == ann) ann `unamb`<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (x `op` y)<br><br>[1] <a href="http://haskell.org/haskellwiki/Unamb">http://haskell.org/haskellwiki/Unamb</a><br>[2] <a href="http://hackage.haskell.org/packages/archive/unamb/latest/doc/html/Data-Unamb.html">http://hackage.haskell.org/packages/archive/unamb/latest/doc/html/Data-Unamb.html</a><br>
[3] <a href="http://conal.net/blog/tag/unamb/">http://conal.net/blog/tag/unamb/</a><br><br>&nbsp;&nbsp; - conal<br><br><div class="gmail_quote">On Mon, Jan 19, 2009 at 12:27 PM, Ryan Ingram <span dir="ltr">&lt;<a href="mailto:ryani.spam@gmail.com">ryani.spam@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div class="Ih2E3d">On Mon, Jan 19, 2009 at 9:10 AM, ChrisK &lt;<a href="mailto:haskell@list.mightyreason.com">haskell@list.mightyreason.com</a>&gt; wrote:<br>

&gt; Consider that the order of pattern matching can matter as well, the simplest<br>
&gt; common case being zip:<br>
&gt;<br>
&gt; zip xs [] = []<br>
&gt; zip [] ys = []<br>
&gt; zip (x:xs) (y:ys) = (x,y) : zip xs ys<br>
<br>
</div>If you are obsessive about least-strictness and performance isn&#39;t a<br>
giant concern, this seems like a perfect use for Conal&#39;s unamb[1]<br>
operator.<br>
<br>
zipR xs [] = []<br>
zipR [] ys = []<br>
zipR (x:xs) (y:ys) = (x,y) : zip xs ys<br>
<br>
zipL [] ys = []<br>
zipL xs [] = []<br>
zipL (x:xs) (y:ys) = (x,y) : zip xs ys<br>
<br>
zip xs ys = unamb (zipL xs ys) (zipR xs ys)<br>
<br>
This runs both zipL and zipR in parallel until one of them gives a<br>
result; if neither of them is _|_ they are guaranteed to be identical,<br>
so we can &quot;unambiguously choose&quot; whichever one gives a result first.<br>
<br>
 &nbsp;-- ryan<br>
<br>
[1] <a href="http://conal.net/blog/posts/functional-concurrency-with-unambiguous-choice/" target="_blank">http://conal.net/blog/posts/functional-concurrency-with-unambiguous-choice/</a><br>
<div><div></div><div class="Wj3C7c">_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
</div></div></blockquote></div><br>