В Elm, как я могу перебрать карту? - PullRequest
0 голосов
/ 26 мая 2018

Я очень плохо знаком с Elm и вообще с FP, но у меня есть небольшой опыт работы с Haskell.Пожалуйста, прости меня, если я не использую правильную терминологию здесь.

Я пытаюсь сделать что-то похожее на XSLT, заменяя шаблоны в XML для преобразования его в HTML.

У меня есть карта шаблонов и замен.Я не совсем уверен, какова лучшая структура данных для этого, но я пытаюсь что-то вроде:

type alias Replacement = { pattern: String, replacement: String }

type ReplacementMap = List Replacement

replacementMap : ReplacementMap
replacementMap = [ { pattern: "<head>", replacement: "<h1>" },
                   { pattern: "<lg>", replacement: "<ul>" },
                   { pattern: "<l>", replacement: "<li>" } ]

И тогда я сделаю что-то вроде:

type alias Xml = String

replacePat : Xml -> Html
replacePat pat repl = replace Regex.All (regex pat) (\_ -> repl)

заменить теги XML head, lg и l их HTML-эквивалентами.Чего я пока не знаю, так это перебрать мой replacementMap, заменяя каждый шаблон его заменой.Или, может быть, есть лучший способ сделать это полностью?

1 Ответ

0 голосов
/ 27 мая 2018

Во-первых, вот рабочий пример:

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>"))

... и т. Д.

...