问题
I've been trying to complete a function that converts double space in a String into a single space in Haskell.
normaliseSpace:: String -> String
normaliseSpace (x:y:xs)= if x==' ' && y==' ' then y:xs
else xs
The problem with my code is that only converts double spaces in the beginning of a String. I suppose it has something to do with pattern matching, but as I am completely new to Haskell I really don't have an idea how to do it. Any help will be appreciated!
回答1:
The reason this happens is because y:xs
and xs
will not recurse on te rest of the string. You thus want to perform the function on the rest of the string.
You thus should call normaliseSpace
on xs
as tail. For example:
normaliseSpace:: String -> String
normaliseSpace "" = ""
normaliseSpace (' ' : ' ' : xs) = ' ' : normaliseSpace xs
normalissSpace (x:xs) = x : normaliseSpace xs
Note that you need to add a pattern for the empty string (list) as well. Since otherwise eventually the recursion will reach the end of the list, and thus raise an error because there is no clause that can "fire".
If you want to reduce a sequence of spaces (two or more to one), then we even need to pass ' ' : xs
through the normalizeSpace
, like @leftroundabout says:
normaliseSpace:: String -> String
normaliseSpace "" = ""
normaliseSpace (' ' : ' ' : xs) = normaliseSpace (' ':xs)
normalissSpace (x:xs) = x : normaliseSpace xs
We can use an as-pattern here, like @JosephSible suggests:
normaliseSpace:: String -> String
normaliseSpace "" = ""
normaliseSpace (' ' : xs@(' ' : _)) = normaliseSpace xs
normalissSpace (x:xs) = x : normaliseSpace xs
回答2:
May be you can simply do like
*Main> let normSpaces = unwords . words
*Main> normSpaces "hello world"
"hello world"
来源:https://stackoverflow.com/questions/58710107/converts-a-double-space-into-single-one-anywhere-in-a-string-in-haskell