Стрелки /HXT и тип подписи

Я пытаюсь изучить Arrows в Haskell, поэтому я пишу простое приложение с библиотекой HXT для XML на основе стрелок. Примеры в вики и руководствах по HXT отказываются от сигнатур типов функций. Однако я очень люблю типы и пытаюсь понять, как их использовать. Здесь я встретил камень преткновения. Учитывая эти функции:

readXml str = runX (readString [withValidate no] str)

atTag tag = deep (isElem >>> hasName tag)

Я полагаю, им должны быть назначены следующие подписи:

readXml ∷ String → IO [XmlTree]

atTag ∷ ArrowXml a ⇒ String → a XmlTree XmlTree

Я пытаюсь соединить их, используя синтаксис стрелки как таковой:

parseItem = proc str -> do
    desc <- text <<< atTag "description" <<< arr readXml -< str
    ...

Однако, если мои мои типовые сигнатуры верны (GHC не жаловался), мне нужен способ, которым можно объединить синтаксис монады и синтаксис стрелки, чтобы получить XmlTree из и вернулся в IO,

Я не уверен, как поступить. У кого-нибудь есть идеи?

1 ответ

Решение

С помощью runX в определении readXml "конвертирует" стрелку в функцию и использует arr в определении parseItem преобразует эту функцию обратно в стрелку снова. Теперь делать это так хорошо, разве что readString возвращает IOStateArrow (псевдоним специального типа для IOSLA - IO State List Arrow), которая должна рассматриваться не только как Arrow, а точнее как IOArrow; Между тем, вы рассматриваете это как чистый Arrow перемотав его с помощью arr,

У вас есть два варианта здесь:

  1. Делать readXml = readString [withValidate no], чтобы readXml :: String -> IOStateArrow s b XmlTree, Тогда вы можете просто сделать ... <<< readXml str в parseItem,
  2. использование arrIO поднять readXml в стрелку ввода-вывода, что позволяет использовать его так, как вы хотели.

Я бы использовал вариант 1 в этом случае, так как кажется, что делать эту развёртывание-развёртывание стрелки излишне, если для этого нет особой причины.

Другие вопросы по тегам