<br><font size=2 face="sans-serif">Today, I reviewed a function I wrote
a few months ago. &nbsp;The function, dropTrailNulls, takes a list of lists
and drops trailing null lists. &nbsp;For instance:</font>
<br>
<br><font size=2 face="sans-serif">*Main&gt; dropTrailNulls [[1],[2,3],[],[]]</font>
<br><font size=2 face="sans-serif">[[1],[2,3]]</font>
<br>
<br><font size=2 face="sans-serif">My original implementation was terrible.
&nbsp;It was recursive, overly bulky, and difficult to understand. &nbsp;It
embarrasses me. &nbsp;I won't post it here.</font>
<br>
<br><font size=2 face="sans-serif">Today, it occurred to me this would
do the trick:</font>
<br>
<br><font size=2 face="sans-serif">dropTrailNulls list = reverse (dropWhile
null (reverse list))</font>
<br>
<br><font size=2 face="sans-serif">The problem is 20 years of experience
writing efficient imperative programs says to me, &quot;You don't drop
things off the end of a structure by reversing the structure, dropping
stuff from the beginning, then reversing again.&quot; &nbsp;I suspect this
imperative bias prevented me from coming up with the simple solution when
I first wrote my function.</font>
<br>
<br><font size=2 face="sans-serif">On the other hand, it is conceivable
to me that my new implementation may actually be relatively efficient since
Haskell uses lazy evaluation, and Haskell lists are constructed from the
tail to the beginning.</font>
<br>
<br><font size=2 face="sans-serif">I'm sure there are many problems that
are encountered in Haskell where it is necessary to operate on the end
of a list. &nbsp;So, I'm wondering if the idiom, reverse, operate, then
reverse is something I should add to my toolbox. &nbsp;Or, is there a more
efficient idiom for addressing these problems?</font>