Стрелки /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
,
У вас есть два варианта здесь:
- Делать
readXml = readString [withValidate no]
, чтобыreadXml :: String -> IOStateArrow s b XmlTree
, Тогда вы можете просто сделать... <<< readXml str
вparseItem
, - использование
arrIO
поднять readXml в стрелку ввода-вывода, что позволяет использовать его так, как вы хотели.
Я бы использовал вариант 1 в этом случае, так как кажется, что делать эту развёртывание-развёртывание стрелки излишне, если для этого нет особой причины.