[Haskell-cafe] Comments and/or Criticisms
derek.a.elkins at gmail.com
Mon Sep 10 18:31:48 EDT 2007
On Mon, 2007-09-10 at 15:47 +1000, Stuart Cook wrote:
> On 9/10/07, PR Stanley <prstanley at ntlworld.com> wrote:
> > Hi
> > Any comments and/or criticisms would be most appreciated:
> > --count the occurrences of char in string
> > countC :: Char -> [Char] -> Int
> > countC x xs = sum [1 | c <- xs, c == x]
> That's a clever implementation, but I think there are clearer ways of
> achieving the same goal. You could replace sum with length and get the
> same answer, at which point the list comprehension isn't buying you
> How about this?
> countC ch xs = length $ filter (ch ==) xs
> > --count occurrences of chars in string
> > countCS :: [Char] -> [(Char, Int)]
> > countCS xs = [(x, (countC x xs)) | x <- [' '..'z'], (countC x xs) > 0]
> A few things to note:
> * Those extra parens around countC are unnecessary; function
> application has highest precedence.
> * [' '..'z'] has a few issues: it misses a few ASCII characters
> (including all the control codes), and won't catch non-ASCII
> * Duplicating the call to countC will probably result in redundant
> evaluation, so it's best to avoid that if possible -- difficult to
> avoid cleanly inside a comprehension though.
> * Scanning the string repeatedly for each potential character ['
> '..'z'] seems excessive, especially if you want to expand it to
> include non-ASCII. Better just to deal with the characters actually in
> the string as they appear, I think.
You can use 'let' in a list comprehension,
[(x,count) | x <- [' '..'z'], let count = countC x xs, count > 0]
More information about the Haskell-Cafe