Re: [Haskell-cafe] Haskell - string to list isusses, and more
On Sun, Jun 14, 2009 at 11:14 AM, Gjuro Chensen daim...@gmail.com wrote: Gjuro Chensen wrote: /cut I dont know everyone will see this, but I would like thank everyone who found time to help, and not spam too much doing it:D. Well, I did it! Its not great (especially comparing to those one line solutions, wow!), but it works. 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: myIsUpper = isUpper for ASCII, so let's just assume that. module Main where startsWithUpper :: String - Bool startsWithUpper []= False startsWithUpper string = if myIsUpper(head(string)) then True else False We can transform this to: startsWithUpper string = isUpper (head string) Under the precondition that the input is not []. So this function has become less general. Now a few systematic transformations to make this smaller: startsWithUpper string = isUpper (head string) startsWithUpper = \string - isUpper (head string) startsWithUpper = isUpper . head That last step because: f . g = \x - f (g x) checkAll string = check (words string) checkAll = \string - check (words string) checkAll = check . words For the same reason as above. check :: [String] - Bool check []=False check x = if all startsWithUpper x then True else False Rewriting the second clause after observing that if p then True else False is the same as p. check [] = False check x = all startsWithUpper x 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. check [] = True check x = all startsWithUpper x Now, in ghci: ghci all undefined [] True 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: check x = all startsWithUpper x And systematic transformations: check = \x - all startsWithUpper x check = all startsWithUpper So that leaves us with: starsWithUpper = isUpper . head checkAll = check . words check = all startsWithUpper Substituting the local definitions: checkAll = all (isUpper . head) . words 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: ghci import Test.SmallCheck ghci smallCheck 10 $ \string - all (not . null) (words string) Depth 0: Completed 1 test(s) without failure. Depth 1: Completed 2 test(s) without failure. Depth 2: Completed 5 test(s) without failure. Depth 3: Completed 16 test(s) without failure. Depth 4: Completed 65 test(s) without failure. Depth 5: Completed 326 test(s) without failure. Depth 6: Completed 1957 test(s) without failure. Depth 7: Completed 13700 test(s) without failure. Depth 8: Completed 109601 test(s) without failure. Depth 9: Completed 986410 test(s) without failure. Depth 10: Completed 9864101 test(s) without failure. So I am reasonably confident that words never gives me any empty strings. Tada! Your solution is almost exactly the same as the one-liners! :-) Luke ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell - string to list isusses, and more
On Mon, Jun 15, 2009 at 3:03 AM, Luke Palmer lrpal...@gmail.com wrote: 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: ghci import Test.SmallCheck ghci smallCheck 10 $ \string - all (not . null) (words string) 'Course, it turns out that SmallCheck never generates any spaces... ever. Some verifier that is. By careful inspection of the definition of words, I can see that it never returns an empty string. I couldn't find a better way to convince myself of this (I like to avoid looking at definitions when possible). Luke Depth 0: Completed 1 test(s) without failure. Depth 1: Completed 2 test(s) without failure. Depth 2: Completed 5 test(s) without failure. Depth 3: Completed 16 test(s) without failure. Depth 4: Completed 65 test(s) without failure. Depth 5: Completed 326 test(s) without failure. Depth 6: Completed 1957 test(s) without failure. Depth 7: Completed 13700 test(s) without failure. Depth 8: Completed 109601 test(s) without failure. Depth 9: Completed 986410 test(s) without failure. Depth 10: Completed 9864101 test(s) without failure. So I am reasonably confident that words never gives me any empty strings. Tada! Your solution is almost exactly the same as the one-liners! :-) Luke ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell - string to list isusses, and more
Am Montag 15 Juni 2009 11:03:36 schrieb Luke Palmer: We can transform this to: startsWithUpper string = isUpper (head string) Under the precondition that the input is not []. So this function has become less general. What about all isUpper . take 1 ? But of course the source reveals that words never puts an empty string into the list. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Haskell - string to list isusses, and more
Hello everyone! Im a Haskell newbie, and Ive have few unanswered questions. For someone more experienced (at least I think so) its a very simple task, but I just cant get a grip on it and its pretty frustrating. It wouldn't be that bad if I haven't browse thru bunch of pages and tutorials and still nothing... The problem is: take a string, and if every words starts with uppercase letter then print yes, else no. Forum Text Bold - yes Frog image File - no Ive had my share of approaches to this, but I just cant make it work. Standard one seemed the most simple: search :: String - String search [] = [] and then use words (splits string on space) to split the string so I could get a list and go through it recursively. But how to apply words to entered string in this form? To find the first letter I came up with: first = take 1 (head x). And compare it with elem or ASCII values to determine if its upper case. Any help, advice or suggestion is appreciated. Thanks in advance! -- View this message in context: http://www.nabble.com/Haskell---string-to-list-isusses%2C-and-more-tp24022673p24022673.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell - string to list isusses, and more
2009/6/14 Gjuro Chensen daim...@gmail.com: Hello everyone! Im a Haskell newbie, and Ive have few unanswered questions. For someone more experienced (at least I think so) its a very simple task, but I just cant get a grip on it and its pretty frustrating. It wouldn't be that bad if I haven't browse thru bunch of pages and tutorials and still nothing... The problem is: take a string, and if every words starts with uppercase letter then print yes, else no. Forum Text Bold - yes Frog image File - no Ive had my share of approaches to this, but I just cant make it work. Standard one seemed the most simple: search :: String - String search [] = [] and then use words (splits string on space) to split the string so I could get a list and go through it recursively. But how to apply words to entered string in this form? To find the first letter I came up with: first = take 1 (head x). And compare it with elem or ASCII values to determine if its upper case. Any help, advice or suggestion is appreciated. Thanks in advance! -- View this message in context: http://www.nabble.com/Haskell---string-to-list-isusses%2C-and-more-tp24022673p24022673.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe As you say, there are a number of possible approaches to take here. I'd say take a look at functions all [1] and isUpper [2], those should be all you need. * all takes a predicate (a function) and a list of elements. It returns True if that predicate holds for all of the elements in the list, otherwise False. * isUpper takes a Char and returns True if that character is an uppercase letter, otherwise False. [1] http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html [2] http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Char.html -- Deniz Dogan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell - string to list isusses, and more
Gjuro Chensen wrote: Hello everyone! Im a Haskell newbie, and Ive have few unanswered questions. For someone more experienced (at least I think so) its a very simple task, but I just cant get a grip on it and its pretty frustrating. It wouldn't be that bad if I haven't browse thru bunch of pages and tutorials and still nothing... The problem is: take a string, and if every words starts with uppercase letter then print yes, else no. Forum Text Bold - yes Frog image File - no Ive had my share of approaches to this, but I just cant make it work. Standard one seemed the most simple: search :: String - String search [] = [] and then use words (splits string on space) to split the string so I could get a list and go through it recursively. But how to apply words to entered string in this form? To find the first letter I came up with: first = take 1 (head x). And compare it with elem or ASCII values to determine if its upper case. The idea of using `words' is very good. If we want to use a bottom-up approach, we should have a function that determines if a word starts with an upper-case letter, i.e. a function of type startsWithUppercase :: String - Bool startsWithUppercase = ... (Hint: look at 'isUpper' from Data.Char) Now we need a way to see if for each word, some predicate is satisfied. There is a standard function for this, all. You can also do this by using map and and. The resulting function can be very concise if you get the hang of it :) Regards, -- Jochem Berndsen | joc...@functor.nl GPG: 0xE6FABFAB ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell - string to list isusses, and more
2009/6/14 Deniz Dogan deniz.a.m.do...@gmail.com: I'd say take a look at functions all [1] and isUpper [2], those should be all you need. Sorry, words is also needed for the idea I was thinking of. -- Deniz Dogan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell - string to list isusses, and more
Am Sonntag 14 Juni 2009 17:19:22 schrieb Gjuro Chensen: Hello everyone! Im a Haskell newbie, and Ive have few unanswered questions. For someone more experienced (at least I think so) its a very simple task, but I just cant get a grip on it and its pretty frustrating. It wouldn't be that bad if I haven't browse thru bunch of pages and tutorials and still nothing... The problem is: take a string, and if every words starts with uppercase letter then print yes, else no. Forum Text Bold - yes Frog image File - no Ive had my share of approaches to this, but I just cant make it work. Standard one seemed the most simple: search :: String - String search [] = [] and then use words (splits string on space) to split the string so I could That's good. So you have everyWordStartsWithAnUppercaseLetter string = doSomething (words string) doSomething :: [String] - Bool checks wordStartsWithAnUppercaseLetter :: String - Bool for each word in the list and returns True if all words satisfy the condition, False if not. There's a handy function in the prelude for that: Prelude :t all all :: (a - Bool) - [a] - Bool get a list and go through it recursively. But how to apply words to entered string in this form? To find the first letter I came up with: first = take 1 (head x). And No, I don't think that's what you want: Prelude :t (take 1 . head) (take 1 . head) :: [[a]] - [a] Since String is a synonym for [Char], head gets the first letter of a word. compare it with elem or ASCII values to determine if its upper case. What about unicode strings? Prelude :t Data.Char.isUpper Data.Char.isUpper :: Char - Bool is what you want. Any help, advice or suggestion is appreciated. Thanks in advance! How to assemble that is left to you. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell - string to list isusses, and more
Here's what I came up with. I especially like the 2nd version, even though it's longer, as it seems very declarative. caps1 s = all (\x - isUpper (head x)) (words s) caps2 s = all startsWithUpper (words s) where startsWithUpper w = isUpper (head w) I'm also fairly new to Haskell, so I would appreciate feedback from the more experienced. Thanks. On Jun 14, 2009, at 11:19 AM, Gjuro Chensen wrote: Hello everyone! Im a Haskell newbie, and Ive have few unanswered questions. For someone more experienced (at least I think so) its a very simple task, but I just cant get a grip on it and its pretty frustrating. It wouldn't be that bad if I haven't browse thru bunch of pages and tutorials and still nothing... The problem is: take a string, and if every words starts with uppercase letter then print yes, else no. Forum Text Bold - yes Frog image File - no Ive had my share of approaches to this, but I just cant make it work. Standard one seemed the most simple: search :: String - String search [] = [] and then use words (splits string on space) to split the string so I could get a list and go through it recursively. But how to apply words to entered string in this form? To find the first letter I came up with: first = take 1 (head x). And compare it with elem or ASCII values to determine if its upper case. Any help, advice or suggestion is appreciated. Thanks in advance! -- View this message in context: http://www.nabble.com/Haskell---string-to-list-isusses%2C-and-more-tp24022673p24022673.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell - string to list isusses, and more
Toby Miller wrote: Here's what I came up with. I especially like the 2nd version, even though it's longer, as it seems very declarative. caps1 s = all (\x - isUpper (head x)) (words s) caps2 s = all startsWithUpper (words s) where startsWithUpper w = isUpper (head w) I'm also fairly new to Haskell, so I would appreciate feedback from the more experienced. This seems fine, but you need to check that words never returns a list containing the empty string (otherwise `head' will fail). I prefer in this case a point free style though, but some might disagree. Cheers, -- Jochem Berndsen | joc...@functor.nl GPG: 0xE6FABFAB ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell - string to list isusses, and more
2009/6/14 Toby Miller t...@miller.ms: Here's what I came up with. I especially like the 2nd version, even though it's longer, as it seems very declarative. caps1 s = all (\x - isUpper (head x)) (words s) caps2 s = all startsWithUpper (words s) where startsWithUpper w = isUpper (head w) I'm also fairly new to Haskell, so I would appreciate feedback from the more experienced. Thanks. Not that I'm very experienced myself, but I came up with the first idea as well: caps1 = all (isUpper . head) . words -- Deniz Dogan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell - string to list isusses, and more
Toby Miller wrote: Here's what I came up with. I especially like the 2nd version, even though it's longer, as it seems very declarative. caps1 s = all (\x - isUpper (head x)) (words s) caps2 s = all startsWithUpper (words s) where startsWithUpper w = isUpper (head w) I'm also fairly new to Haskell, so I would appreciate feedback from the more experienced. Thanks. caps = all (isUpper . head) . words But then, I'm strange like that... ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell - string to list isusses, and more
2009/6/14 Jochem Berndsen joc...@functor.nl: Toby Miller wrote: caps1 s = all (\x - isUpper (head x)) (words s) This seems fine, but you need to check that words never returns a list containing the empty string (otherwise `head' will fail). Is there any such case? I was thinking about that as well, but couldn't think of any case where head would be called on an empty list. -- Deniz Dogan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell - string to list isusses, and more
Deniz Dogan wrote: 2009/6/14 Jochem Berndsen joc...@functor.nl: Toby Miller wrote: caps1 s = all (\x - isUpper (head x)) (words s) This seems fine, but you need to check that words never returns a list containing the empty string (otherwise `head' will fail). Is there any such case? I was thinking about that as well, but couldn't think of any case where head would be called on an empty list. Not that I know of; but I tested this in order to make sure that I didn't overlook something obvious. (At least, it's a potential issue that we need to check, since `head' is partial.) Regards, -- Jochem Berndsen | joc...@functor.nl GPG: 0xE6FABFAB ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell - string to list isusses, and more
Gjuro Chensen wrote: /cut I dont know everyone will see this, but I would like thank everyone who found time to help, and not spam too much doing it:D. Well, I did it! Its not great (especially comparing to those one line solutions, wow!), but it works. module Main where startsWithUpper :: String - Bool startsWithUpper []= False startsWithUpper string = if myIsUpper(head(string)) then True else False myIsUpper :: Char - Bool myIsUpper x = if x='A' x = 'Z' then True else False checkAll string = check (words string) check :: [String] - Bool check []=False check x = if all startsWithUpper x then True else False Since importing modules isnt allowed, I made my own isUpper. And thats it, for few days of Haskell, Im happy. Once again, many many thanks to everyone! -- View this message in context: http://www.nabble.com/Haskell---string-to-list-isusses%2C-and-more-tp24022673p24023759.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell - string to list isusses, and more
Gjuro Chensen wrote: startsWithUpper :: String - Bool startsWithUpper []= False startsWithUpper string = if myIsUpper(head(string)) then True else False It is very good that you caught the issue of taking the head of an empty list :) I saw here and also below, that you did things like if P then True else False You can shorten this to 'P'. Also, normally Haskellers like to pattern match, changing the second clause of your function into startsWithUpper (x:xs) = myIsUpper x check :: [String] - Bool check []=False Why is this False and not True? Certainly in the empty string all words start with an uppercase letter, don't they? (If it's True, you can even remove this clause, and let the other one take care of the rest.) Regards, -- Jochem Berndsen | joc...@functor.nl GPG: 0xE6FABFAB ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe