Real World Haskell, глава 4, стр. 98 печати спрашивает, words
можно ли реализовать с помощью сгибов, и это тоже мой вопрос:
Является ли это возможным? Если нет, то почему? Если это так, как?
Я придумал следующее, которое основано на идее, что каждый непробел должен быть добавлен перед последним словом в списке вывода (это происходит в otherwise
охране), и что пробел должен инициировать добавление слова 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) не есть функция, которая обеспечивает окончательный вывод из коробки; всегда есть что-то, с чем нужно как-то настроить выход.
Поэтому я возвращаюсь к первоначальному вопросу и спрашиваю, возможно ли на самом деле реализовать words
(таким образом, чтобы он правильно обрабатывал конечные / ведущие / повторные пробелы), используя сгибы. С помощью сгибов я имею в виду , что функция складывания должна быть внешняя функция:
myWords :: String -> [String]
myWords input = foldr step seed input
источник
["xa"] == words "xa" == step 'x' (words "a") == step 'x' (words " a") == words "x a" == ["x", "a"]
, преимущество которого состоит в том, чтобы быть действительным аргументом для любого направления сгибаУ @chi есть замечательный аргумент, который вы не можете реализовать,
words
используя фолд "а", но вы сказали, что фолд s .И самая внешняя и самая внутренняя функция - сгибы. ;-)
источник
Да. Даже если это немного сложно, вы все равно можете делать эту работу правильно, используя один
foldr
и ничего больше, если вы углубляетесь в CPS ( Continuation Passing Style ). Я показал особый видchunksOf
функции ранее.В таких типах сгибов наш аккумулятор, следовательно, результат сгиба является функцией, и мы должны применить его к входному идентификатору, чтобы получить конечный результат. Так что это может считаться конечной стадией обработки или нет, так как мы используем здесь единственную складку, и тип ее включает функцию. Открыта для обсуждения :)
sf
: Начальное значение функции для начала.go
: Функция итератораНа самом деле мы здесь не полностью используем силу CPS, поскольку в каждом ходу у нас есть как предыдущий, так
pc
и правильный символc
. Это было очень полезно вchunksOf
функции, упомянутой выше, при разбиении[Int]
на[[Int]]
каждый раз, когда восходящая последовательность элементов была нарушена.источник