[Haskell-beginners] Re: Defining 'words' in terms of 'span'

Heinrich Apfelmus apfelmus at quantentunnel.de
Wed Mar 17 05:10:27 EDT 2010


Roger Whittaker wrote:
> Thanks for the suggestions - I think the idea was that you had to
> use a recursive definition in terms of span.
> 
> I eventually did this, but didn't feel it was at all nice or
> elegant:
> 
> import Data.Char
> 
> mywords :: [Char] -> [[Char]]
> 
> mywords l |  ((snd (span isAlpha l)) == "" && (fst (span isAlpha l)) == "") = []
>           |  ((snd (span isAlpha l)) == "" && (fst (span isAlpha l)) /= "") = [fst (span isAlpha l)]
>           |  (fst (span isAlpha l))  == "" =  mywords (tail (snd (span isAlpha l)))
>           |  otherwise = [fst (span isAlpha l)] ++ mywords (tail (snd (span isAlpha l)))

You can perform a few simple steps to improve this definition. First of
all, introduce a variable for the the common  span isAlpha  part and use
pattern matching instead of  fst  and  snd .

    mywords xs
        |  r == "" && l == "" = []
        |  r == "" && l /= "" = [l]
        |  l == "" =  mywords (tail r)
        |  otherwise = [l] ++ mywords (tail r)
        where
        (l,r) = span isAlpha xs

There, much better already.

Then, you can group the four different cases, noting that they are
actually independent of each other: the result is always a concatenation
of either  []  or  [l]  with either  []  or  mywords (tail r)

    mywords xs = y ++ ys
        where
        (l,r) = span isAlpha xs
        y     = if l == "" then [] else [l]
        ys    = if r == "" then [] else mywords (tail r)



Regards,
Heinrich Apfelmus

--
http://apfelmus.nfshost.com



More information about the Beginners mailing list