On Sun, Jun 14, 2009 at 11:14 AM, Gjuro Chensen <span dir="ltr"><<a href="mailto:daimaox@gmail.com">daimaox@gmail.com</a>></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>
><br>
><br>
> /cut<br>
><br>
><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'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't know if you'll find this interesting, but I do, so here goes:<br>
<br>myIsUpper = isUpper for ASCII, so let'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 -> 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 -> isUpper (head string)<br>startsWithUpper = isUpper . head<br><br>That last step because:<br><br>f . g = \x -> 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 -> 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] -> 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 "if p then True else False" is the same as "p".<br><br>check [] = False<br>check x = all startsWithUpper x<br><br>
I'm going to take Jochem's suggestion and change the empty clause to True: "all words start with an upper case letter" is equivalent to "there is no word which does not start with an upper case letter", 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> 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 "monotone" 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 -> 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> import Test.SmallCheck<br>ghci> smallCheck 10 $ \string -> 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>