Haskell变量赋值问题:多空格合并函数编译报错咨询
Let's walk through what's causing that parse error and build a working solution for your problem.
First, the Immediate Error
The parse error on = happens because Haskell doesn't allow assignment inside expressions. In your code, you wrote:
if isInfixOf " " index then index = " " else index
The index = " " part is invalid here—Haskell uses = to define bindings (like function definitions), not to mutate variables (since it's a pure functional language). That's why the compiler throws a fit.
Next, Fixing the Logic
Even if we fixed the syntax, your current logic doesn't actually handle multiple spaces—it just checks if a space exists at all. To collapse consecutive spaces into one, we have two great options:
Option 1: Use Standard Library Functions (Simplest!)
Haskell's standard library has words and unwords which do exactly what we need:
wordssplits a string into a list of words, ignoring any number of whitespace characters between them.unwordsjoins that list back into a single string, with exactly one space between each word.
Here's the one-liner:
getSpaces :: String -> String getSpaces = unwords . words
Try this in GHCI—getSpaces "hello world foo" will return "hello world foo" perfectly.
Option 2: Manual Recursive Implementation (Great for Learning)
If you want to build the logic yourself to understand how it works, here's a recursive version:
getSpaces :: String -> String -- Base case: empty string stays empty getSpaces [] = [] -- If we hit a space, keep one space, then skip all following consecutive spaces getSpaces (' ':xs) = ' ' : getSpaces (dropWhile (== ' ') xs) -- For non-space characters, just keep the char and recurse on the rest getSpaces (x:xs) = x : getSpaces xs
Let's break this down:
- When we see a space, we add one space to the result, then use
dropWhileto skip every subsequent space before continuing the recursion. - For non-space characters, we just append the character to the result and keep processing the rest of the string.
Quick Notes on Your Original Code
- The parameter name
indexis a bit confusing here—since it's a full string, something likestrorswould be more readable. - Checking
length index == 1is unnecessary; both solutions above handle single-character strings correctly automatically.
内容的提问来源于stack exchange,提问作者Dan Hessler

