88
Решение. Искомая функция должна осуществлять последовательный
просмотр символов исходного текста, преобразуя его в список строк
(«слов»). Задачи последовательного просмотра списка и применения к его
элементам некоторой функции удобно записывать с помощью одной из
двух стандартных функций высших порядков – map или foldr. Функцию
map удобнее применять в том случае, когда
результат обработки сохраняет
структуру списка-аргумента, а функцию foldr – в том случае, когда эта
структура меняется. В данном случае список символов превращается в
список строк, так что функция map для решения задачи не подходит.
Функцию foldr применить можно, если определить, каким образом
очередной элемент исходного списка преобразует формирующийся
результат. Тогда, если
задать подходящее начальное значение seed, то
искомую функцию можно будет получить в виде выражения foldr f
seed, где f – функция обработки очередного элемента, а f – выбранное
начальное значение.
В данной задаче начальным значением может быть список,
содержащий единственное пустое слово, а функция обработки очередного
символа должна либо присоединять этот символ к первой
строке списка,
либо образовывать новое слово. Поясним эту идею на примере.
Пусть исходная строка выглядит следующим образом.
"На берегу пустынных волн стоял он, дум великих полн."
Пусть конец строки уже обработан (напомним, что функция foldr
обрабатывает список в направлении от конца к началу), и при этом
получен список слов
["ум", "великих", "полн."]
а очередным символом для обработки, соответственно, является символ
'д'. Поскольку этот символ не является пробелом, то его нужно просто
присоединить к первому слову формирующегося списка, при этом
получится
["дум", "великих", "полн."]
Очередным обрабатываемым символом будет пробел. В этом случае
наша функция должна образовать новое слово в списке, так что список
будет иметь вид
["", "дум", "великих", "полн."]
Если слова в исходной строке разделяются ровно одним пробелом,
то описанных двух случаев достаточно для обработки всей исходной
строки. Если разделяющих пробелов может быть несколько, то для того,
чтобы в списке не образовывались пустые слова, надо предусмотреть еще
один случай – когда очередным обрабатываемым символом является
пробел, а в списке слов первое
слово – пустое. В этом случае пробел
просто пропускается.
Итак, опишем функцию glue с двумя аргументами – символом и
списком строк, которая присоединяет очередной символ к списку строк