Question

I have just started programming with Haskell and would like to do a String transformation. I have an arbitrary String e.g. " abcd \n dad " I would like to remove the whitespace characters on the left and on the right. And I would like to eliminate multiple whitespaces as well as escape sequcences " \n " -> " "

So the String above would look like this "abcd dad"

I have already written a function that trims the String and removes the whitespace characters (I'm removing the character if isSpace is true):

trim :: [Char] -> [Char]
trim x = dropWhileEnd isSpace (dropWhile isSpace x)

Now my idea is to do a pattern matching on the input String. But how do I apply the trim function directly to the input? So at first I would like to trim the String at both ends and then apply a pattern matching. So the only thing I would have to do is comparing two characters and removing one if both are whitespace characters

    --How do I apply trim directly to the input
    s :: [Char] -> [Char]
    s [x] = [x]
    s(x:xx) = ...

Note: Efficiency is not important. I would like to learn the concepts of pattern matching and understand how Haskell works.

Cheers

Was it helpful?

Solution 2

If you want to pattern-match on the output of trim, you have to call trim, of course! For example, if you want cases for lists of length 0, 1, and longer, you could use

s xs = case trim xs of
    [] -> ...
    [x] -> ...
    x:x':xs -> ...

OTHER TIPS

trim = unwords . words

Examine the source of words in the Prelude.

Your first pattern matches a single character and returns it. Surely this is not what you want - it could be whitespace. Your first match should be the empty list.

If you were only removing space chars, you could do something like this:

trim :: [Char] -> [Char]
trim [] = []
trim (' ':xs) = trim xs
...

You should be able to see that this removes all leading spaces. At this point, either the string is empty (and matches the first pattern) or it falls through to... leaving that up to you.

If you want to remove all whitespace, you need a list or set of those characters. That might look like this:

trim :: [Char] -> [Char]
trim = let whitespace = [' ', '\t\, `\v'] -- There are more than this, of course
       in t
       where
         t [] = []
         t (x:xs) | elem x whitespace = t xs
                  | otherwise = ...

Again, this has shown how to match the beginning part of the string. Leave it up to you to think about getting to the end.

You can also do pattern matching in a nested function:

s str = removeInnerSpaces (trim str)
  where
    removeInnerSpaces [] = []
    removeInnerSpaces (x:xs) = ...

Here removeInnerSpaces is a nested function, local to s.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top