Почему я не могу переназначить индекс на один пробел?
Потому что в Хаскеле вы не можете ничего переназначить. На самом деле вы никогда даже не назначаете , вы объявляете (это что-то связанное, но другое). Даже в некоторых случаях, когда это может выглядеть так, как будто вы переназначаете переменные (как в do
блоках, вы не переназначаете, но вы shadow переменные объявляете новую переменную с тем же именем, опять же, это немного связано, но во многих случаях мы видим другое поведение, например, в цикле мы не можем скрывать переменную каждую итерацию).
Чтобы ответить на ваш вопрос, вы, вероятно, захотите вернуть строку с одним пробелом, мы можем сделать это, написав:
getSpaces index = if (length index) == 1 then index else
if isInfixOf " " index then <b>" "</b> else index
Но, тем не менее, это все еще довольно не элегантно, а также довольно небезопасно, поскольку в случае бесконечного String
это начнет циклически повторяться: length
продолжает циклировать, пока список (символов) не будет исчерпан, и Вполне возможно, что этого никогда не произойдет. Более того, даже если он не застревает в бесконечном цикле, он все равно не рекомендуется, поскольку он работает в O (n) (с n длиной списка). Так что для длинных списков это неэффективно.
Обычно в Haskell используется комбинация шаблонов и охранников , чтобы различать возможные значения. Ваш случай может быть сопоставлен с:
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 = " "