Удалить символы из строки во всех элементах списка - PullRequest
0 голосов
/ 21 апреля 2019

Я пытаюсь заменить все строки, которые содержат подстроку, в списке. Я пробовал с помощью функции map:

cleanUpChars = map(\w -> if isInfixOf "**" w then map(\c ->  if c == "*" then ""; else c); else w)

Для меня это звучит так: элементы карты в списке, например, если символ слова содержит *, то заменить его ничем

Хаскеллу: «Не удалось сопоставить ожидаемый тип [[Char]] -> [[Char]] с фактическим типом [Char] в выражении: w» (и последний w подчеркнут)

Любая помощь приветствуется

1 Ответ

2 голосов
/ 21 апреля 2019

Чтобы ответить на пересмотренный вопрос (когда isInfixOf было правильно import отредактировано):

cleanUpChars = map(\w -> if isInfixOf "**" w then map(\c ->  if c == "*" then ""; else c); else w)

Самая очевидная ошибка здесь в том, что c во внутренних скобках будет Char (поскольку это вход для функции, которая map ped по String) - и символы используют одинарные кавычки , а не двойные кавычки. Это не просто случай опечатки или неправильного синтаксиса, однако - "" отлично работает как пустая строка (и эквивалентно [], так как строки - просто списки), но не существует такой вещи, как «пустой» характер».

Если, как вам кажется, ваша цель состоит в том, чтобы удалить все * s из каждой строки в списке, содержащей **, то правильный инструмент - filter, а не map:

Prelude Data.List> cleanUpChars = map(\w -> if isInfixOf "**" w then filter (/= '*') w; else w)
Prelude Data.List> cleanUpChars ["th**is", "is", "a*", "t**es*t"]
["this","is","a*","test"]

(Обратите внимание, что в примере, который я составил, он удаляет все звездочки из t**es*t, даже одну. Это может быть не то, что вы на самом деле хотели, но это то, что подразумевает ваша логика в ошибочной версии - вы должны быть немного более сложными, чтобы удалить только пары последовательных *.)

PS Я бы, конечно, никогда не писал такую ​​функцию с точкой с запятой - она ​​действительно ничего вам не дает. Я также хотел бы использовать инфиксную форму isInfixOf, которая делает более понятным, какую строку вы ищете внутри другой:

cleanUpChars :: [String] -> [String]
cleanUpChars = map (\w -> if "**" `isInfixOf` w then filter (/= '*') w else w)

Я все еще не особенно доволен этим для читабельности - возможно, есть какой-то хороший способ привести в порядок это, что я пока пропускаю. Но даже если это не так, это помогает читабельности imo дать функции локальное имя (надеюсь, вы можете придумать более краткое имя, чем моя версия!):

cleanUpChars :: [String] -> [String]
cleanUpChars = map possiblyRemoveAsterisks
    where possiblyRemoveAsterisks w = if "**" `isInfixOf` w then filter (/= '*') w else w
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...