Реальный мир Haskell, глава 4, стр. 98 печати спрашивает, можно ли реализовать words
, используя сгибы, и это тоже мой вопрос:
Является ли это возможным? Если нет, то почему? Если да, то как?
Я придумал следующее, основанное на идее, что каждый непробел должен быть добавлен перед последним словом в списке вывода (это происходит в otherwise
guard), и пробел должен инициировать добавление слова emtpy в список вывода, если его еще нет (это обрабатывается в if
- then
- else
).
myWords :: String -> [String]
myWords = foldr step [[]]
where
step x yss@(y:ys)
| x == ' ' = if y == "" then yss else "":yss
| otherwise = (x:y):ys
Очевидно, что это неправильное решение, так как начальные пробелы во входной строке приводят к одной ведущей пустой строке в выходном списке строк.
По ссылке выше я рассмотрел несколько из предложенные решения для других читателей, и многие из них работают аналогично моему решению, но обычно они «обрабатывают» вывод сгиба, например, tail
, если есть пустая начальная строка.
В других подходах используются кортежи (фактически просто пары), так что фолд имеет дело с парой и может хорошо обрабатывать начальные / конечные пробелы.
Во всех этих подходах foldr
(или другой фолд, fwiw) не является функцией, которая обеспечивает окончательный вывод из коробки; всегда есть что-то, с чем нужно как-то настроить вывод.
Поэтому я go возвращаюсь к первоначальному вопросу и спрашиваю, возможно ли на самом деле реализовать words
(таким образом, чтобы он правильно обрабатывал трейлинг / ведущие / повторные пробелы) с использованием складок. Под с использованием сгибов я имею в виду, что функция сгибания должна быть самой внешней функцией:
myWords :: String -> [String]
myWords input = foldr step seed input