Реальний світ Haskell, глава 4, сторінка 98 друку запитує, чи words
можна реалізувати за допомогою складок, і це також моє питання:
Це можливо? Якщо ні, то чому? Якщо так, то як?
Я придумав наступне, що ґрунтується на ідеї, що кожне не пробіл має бути попередньо до останнього слова у списку виводу (це відбувається у otherwise
захисті), і пробіл повинен викликати додавання порожнього слова до список вихідних даних, якщо його вже немає (це обробляється у 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