# [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

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

```