On Sun, Jun 14, 2009 at 11:14 AM, Gjuro Chensen <span dir="ltr">&lt;<a href="mailto:daimaox@gmail.com">daimaox@gmail.com</a>&gt;</span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
Gjuro Chensen wrote:<br>
&gt;<br>
&gt;<br>
&gt; /cut<br>
&gt;<br>
&gt;<br>
<br>
I dont know everyone will see this, but I would like thank everyone who<br>
found time to help, and not spam too much doing it:D.<br>
Well, I did it! Its not great (especially comparing to those one line<br>
solutions, wow!), but it works.</blockquote><div><br>Nice work.  For fun, I&#39;m going to semi-formally transform your solution into the one-liner that was given (multiple times).   Systematic transformation is one of the great joys of functional programming.  I don&#39;t know if you&#39;ll find this interesting, but I do, so here goes:<br>
<br>myIsUpper = isUpper for ASCII, so let&#39;s just assume that.<br> <br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
module Main where<br>
<br>
startsWithUpper :: String -&gt; Bool<br>
startsWithUpper []= False<br>
startsWithUpper string =<br>
        if myIsUpper(head(string)) then True<br>
        else False</blockquote><div><br>We can transform this to:<br><br>startsWithUpper string = isUpper (head string)<br><br>Under the precondition that the input is not [].  So this function has become less general.  Now a few systematic transformations to make this smaller:<br>
<br>startsWithUpper string = isUpper (head string)<br>startsWithUpper = \string -&gt; isUpper (head string)<br>startsWithUpper = isUpper . head<br><br>That last step because:<br><br>f . g = \x -&gt; f (g x) <br><br></div>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
checkAll string = check (words string)</blockquote><div><br>checkAll = \string -&gt; check (words string)<br>checkAll = check . words<br><br>For the same reason as above. <br><br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">

check :: [String] -&gt; Bool<br>
check []=False<br>
check x =<br>
        if all startsWithUpper x then True<br>
        else False</blockquote><div><br>Rewriting the second clause after observing that &quot;if p then True else False&quot; is the same as &quot;p&quot;.<br><br>check [] = False<br>check x = all startsWithUpper x<br><br>
I&#39;m going to take Jochem&#39;s suggestion and change the empty clause to True: &quot;all words start with an upper case letter&quot; is equivalent to &quot;there is no word which does not start with an upper case letter&quot;, which is true for an empty list.<br>
<br>check [] = True<br>check x = all startsWithUpper x<br><br>Now, in ghci:<br><br>ghci&gt; all undefined []<br>True<br><br>Since this returned True for undefined, it will return True for any argument whatsoever there (this is called the &quot;monotone&quot; property, and all Haskell functions obey it).  Therefore, we can remove the empty list clause:<br>
<br>check x = all startsWithUpper x<br><br>And systematic transformations:<br><br>check = \x -&gt; all startsWithUpper x<br>check = all startsWithUpper<br> <br><br>So that leaves us with:<br><br>starsWithUpper = isUpper . head<br>
checkAll = check . words<br>check = all startsWithUpper<br><br>Substituting the local definitions:<br><br>checkAll = all (isUpper . head) . words<br><br>The last thing: we made startsWithUpper less general in the process; it is undefined for empty strings.  We need to verify that words never returns any empty strings.  I did this using SmallCheck:<br>
<br>ghci&gt; import Test.SmallCheck<br>ghci&gt; smallCheck 10 $ \string -&gt; all (not . null) (words string)<br>Depth 0:<br>  Completed 1 test(s) without failure.<br>Depth 1:<br>  Completed 2 test(s) without failure.<br>
Depth 2:<br>  Completed 5 test(s) without failure.<br>Depth 3:<br>  Completed 16 test(s) without failure.<br>Depth 4:<br>  Completed 65 test(s) without failure.<br>Depth 5:<br>  Completed 326 test(s) without failure.<br>Depth 6:<br>
  Completed 1957 test(s) without failure.<br>Depth 7:<br>  Completed 13700 test(s) without failure.<br>Depth 8:<br>  Completed 109601 test(s) without failure.<br>Depth 9:<br>  Completed 986410 test(s) without failure.<br>
Depth 10:<br>  Completed 9864101 test(s) without failure.<br><br>So I am reasonably confident that words never gives me any empty strings.<br><br>Tada!  Your solution is almost exactly the same as the one-liners! :-)<br><br>
Luke<br></div></div><br>