我试图编写一个接受字符串的辅助函数,如果字符串有多个空格,则将其转换为一个字符串。这是代码:
getSpaces :: String -> String
getSpaces index =
if (length index) == 1 then index
else
if isInfixOf " " index then index = " "
else index
当我尝试将模块加载到GHCI时,我收到错误:
Prelude> :l Utilities
[1 of 1] Compiling Utilities ( Utilities.hs, interpreted )
Utilities.hs:55:42: error:
parse error on input ‘=’
Perhaps you need a 'let' in a 'do' block?
e.g. 'let x = 5' instead of 'x = 5'
|
55 | if isInfixOf " " index then index = " "
| ^
Failed, no modules loaded.
为什么我无法将索引重新分配给单个空格?
答案 0 :(得分:8)
为什么我无法将索引重新分配给单个空格?
因为在Haskell中你无法重新分配任何东西。事实上你甚至从未分配,你声明(这是相关的,但不同的)。即使在某些情况下,您可能看起来像是重新分配变量(例如在do
块中,您不会重新分配,而是通过声明一个具有相同名称的新变量来影子变量这有点相关,但是在很多情况下我们会看到不同的行为,例如在循环中,我们不能在每次迭代时遮蔽变量。)
要回答你的问题,你可能想要返回一个带有一个空格的字符串,我们可以写一下:
getSpaces index = if (length index) == 1 then index else
if isInfixOf " " index then " " else index
但是这仍然相当不优雅,而且相当不安全,因为在无限String
的情况下,这将开始循环:length
保持循环直到列表(字符)已经筋疲力尽了,这可能永远不会发生。此外,即使它没有陷入无限循环,那么仍然不建议,因为它在 O(n)中运行( n 列表的长度)。所以对于长列表来说,效率很低。
通常在Haskell中,使用模式和 guards 的组合来区分可能的值。您的案例可以映射到:
getSpaces :: String -> String
getSpaces st@[_] = st
getSpaces st | isInfixOf " " st = st
| otherwise = " "
然而,如果列表具有无限大小,则sinze isInfixOf
会一直寻找空格,直到找到空格,或者String
已用尽。
由于isPrefixOf
作为搜索模式,带有一个字符的字符串实际上意味着我们查看字符串是否包含空格,我们可以将其替换为elem
并查看对于角色' '
:
getSpaces :: String -> String
getSpaces st@[_] = st
getSpaces st | elem ' ' st = st
| otherwise = " "
答案 1 :(得分:1)
我找到了修复,而不是更改索引,我只是返回一个空格。
Insead of:
if isInfixOf " " index then index = " "
我做了:
if isInfixOf " " index then " "
所以我只是回到空间。