words with fold

Real World Haskell, Exercise 10, p. 98: Write the words function using list folds:

myWords :: String -> [String]
myWords s = reverse (foldr step [] (trim s))

step :: Char -> [String] -> [String]
step c [] = [c:[]]
step c acc 
    | (isSpace c) = acc ++ [""]
    | otherwise = (take ((length acc) - 1) acc) ++ [c:(last acc)]

isSpace :: Char -> Bool
isSpace ' '  = True
isSpace '\n' = True
isSpace '\r' = True
isSpace '\t' = True
isSpace _    = False

lstrip :: String -> String
lstrip [] = ""
lstrip (x:xs) 
  | (isSpace x) = lstrip xs
  | otherwise = x:xs

rstrip :: String -> String
rstrip s = reverse (lstrip (reverse s))

trim :: String -> String
trim = lstrip . rstrip

Moral of this exercise: you can only pass a list to ++. You can’t use ++ to append a Char to a String. You have to append [c] instead.

There’s probably an isSpace function in the standard library somewhere I could be using instead. (Found it. It’s Char.isSpace)

The trim function feels unnecessary. A more clever implementation of the fold might avoid it.

And that reverse is really yucky. I should be able to rewrite the fold so the values come out in the right order.

Leave a Reply