Я пытаюсь смириться с XML Toolbox на Haskell ( HXT ) и где-то бью стену, потому что мне кажется, что я не совсем понимаю стрелки как вычислительный инструмент.
Вот моя проблема, которую я надеялся проиллюстрировать немного лучше, используя сеанс GHCi:
> let parse p = runLA (xread >>> p) "<root><a>foo</a><b>bar</b><c>baz</c></root>"
> :t parse
parse :: LA XmlTree b -> [b]
Итак, Parse - это маленькая вспомогательная функция, которая применяет любую стрелку, которую я даю, к тривиальному XML-документу
<root>
<a>foo</a>
<b>bar</b>
<c>baz</c>
</root>
Я определяю другую вспомогательную функцию, на этот раз для извлечения текста под узлом с заданным именем:
> let extract s = getChildren >>> isElem >>> hasName s >>> getChildren >>> getText
> :t extract
extract :: (ArrowXml cat) =>
String -> cat (Data.Tree.NTree.TypeDefs.NTree XNode) String
> parse (extract "a" &&& extract "b") -- extract two nodes' content.
[("foo","bar")]
С помощью этой функции легко использовать комбинатор &&&
для объединения текста двух разных узлов, а затем, скажем, передать его конструктору, например так:
> parse (extract "a" &&& extract "b" >>^ arr (\(a,b) -> (b,a)))
[("bar","foo")]
Теперь приходит часть, которую я не понимаю: я хочу уйти! extract
дважды вызывает getChildren
на корневом узле. Вместо этого я бы хотел, чтобы он назывался только один раз! Поэтому я сначала получаю дочерний узел корневого узла
> let extract' s = hasName s >>> getChildren >>> getText
> :t extract'
extract' :: (ArrowXml cat) => String -> cat XmlTree String
> parse (getChildren >>> isElem >>> (extract' "a" &&& extract' "b"))
[]
Обратите внимание, что я попытался изменить порядок вызовов, скажем, isElem и т. Д., Чтобы выяснить, в этом ли проблема. Но в настоящее время я просто не знаю, почему это не работает. На вики Haskell есть стрелка 'tutorial' , и, как я понял, должно иметь возможность делать то, что я хочу, - а именно использовать &&&
в Для того чтобы объединить результаты двух вычислений.
Это тоже работает - но только в начале цепочки стрелок, а не в середине желоба, когда у меня уже есть какие-то результаты, которые я хочу оставить «общими». У меня такое ощущение, что я просто не в состоянии обернуть голову в разницу между идеями о нормальной композиции функций и обозначениях стрелок. Я был бы очень благодарен за любые указатели! (Даже если это просто какое-то общее руководство по стрелкам, которое идет немного глубже, чем в вики на Haskell.)
Спасибо!