Во-первых, вот рабочий пример:
import Html exposing (text)
import Regex as R
type alias Replacement = { pattern: R.Regex, replacement: String }
type alias ReplacementMap = List Replacement
type alias Xml = String
main =
let
replacements =
[ { pattern = R.regex "<head>", replacement = "<h1>" }
, { pattern = R.regex "</head>", replacement = "</h1>" }
, { pattern = R.regex "<lg>", replacement = "<ul>" }
, { pattern = R.regex "</lg>", replacement = "</ul>" }
, { pattern = R.regex "<l>", replacement = "<li>" }
, { pattern = R.regex "</l>", replacement = "</li>" }
]
example = "<head>Foo</head>"
in
text (replacePat example replacements)
replace : Replacement -> Xml -> Xml
replace replacement xml =
R.replace R.All replacement.pattern (always replacement.replacement) xml
replacePat : Xml -> ReplacementMap -> String
replacePat xml rmap =
List.foldl replace xml rmap
Для решения проблемы сначала рассмотрите ваши входы и выходы:
ВХОДЫ: List
заменшаблоны и String
XML.
ВЫХОДЫ: A String
HTML
Если у вас есть коллекция, например List
, и вы хотитечтобы получить единственную вещь (например, String
), которая является подсказкой, что вам нужно выполнить какое-то сокращение: вы переходите от многих к одному.Уменьшение List
обычно означает, что вы будете делать сгиб (foldl
или foldr
).
foldr
перебирает список, применяя предоставленную функцию (в данном случае replace
) кэлемент в списке и предыдущий результат применения функции;За исключением первой итерации, во время которой используется начальное значение (исходный XML в вашем случае).Это вызывает ... эффект конкатенации, поскольку итерация продолжается.Наконец, результат последнего применения функции возвращается в качестве конечного значения.
Другими словами, List.foldl replace xml rmap
- это то же самое, что и набор приложений вложенных функций (вызовов):
replace
{ pattern = R.regex "<lg>", replacement = "<ul>" }
(replace
{ pattern = R.regex "</head>", replacement = "</h1>" }
(replace
{ pattern = R.regex "<head>", replacement = "<h1>" }
"<head>Foo</head>"))
... и т. Д.