Domanda

sto cercando di venire a patti con Haskell XML Toolbox ( HXT ) e ho' m colpire un qualche muro, perché non mi sembra di cogliere appieno le frecce come strumento di calcolo.

Ecco il mio problema, che speravo di illustrare un po 'meglio utilizzando una sessione 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]

Quindi Parse è una piccola funzione di supporto che si applica indipendentemente freccia lo do al documento XML banale

<root>
  <a>foo</a>
  <b>bar</b>
  <c>baz</c>
</root>

Mi definisco un'altra funzione di supporto, questa volta per estrarre il testo qui sotto un nodo con un determinato nome:

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

Con l'aiuto di questa funzione, è facile da usare il Combinator &&& per accoppiare il testo di due nodi differenti, e quindi, ad esempio, passare ad un costruttore, in questo modo:

> parse (extract "a" &&& extract "b" >>^ arr (\(a,b) -> (b,a))) 
[("bar","foo")]

Ora viene la parte che non capisco: io voglio sinistra-factor! chiamate extract getChildren sulla radice-nodo due volte. Invece, mi piacerebbe che chiamare solo una volta! Così ho capito che il bambino del nodo principale

> let extract' s = hasName s >>> getChildren >>> getText
> :t extract'
extract' :: (ArrowXml cat) => String -> cat XmlTree String
> parse (getChildren >>> isElem >>> (extract' "a" &&& extract' "b"))
[]

Si noti che ho cercato di riordinare le chiamate a, diciamo, isElem, ecc al fine di scoprire se questo è il problema. Ma così com'è, solo che non ho alcuna idea del perché questo non sta funzionando. C'è una freccia 'dimostrativi' sul Haskell wiki e il modo in cui ho capito, è dovrebbe essere possibile fare quello che voglio fare in quel modo -. vale a dire utilizzare &&& al fine di accoppiare i risultati di due calcoli

Si fa il lavoro, anche - ma solo all'inizio della freccia-chain, attraverso non a metà strada, quando ho alcuni risultati già, che voglio mantenere 'condivisa'. Ho la sensazione che sto solo non essere in grado di avvolgere la mia testa intorno una differenza di idee tra composizione normale funzione e freccia di notazione. Sarei molto riconoscente di tutti i puntatori! (Anche se è solo a qualche generica freccia dimostrativi che va un po 'più in profondità rispetto al sul Haskell-wiki).

Grazie!

È stato utile?

Soluzione

Se si converte la freccia a (e poi da) una versione deterministica Questo funziona come previsto:

> let extract' s = unlistA >>> hasName s >>> getChildren >>> getText
> parse (listA (getChildren >>> isElem) >>> (extract' "a" &&& extract' "b"))
[("foo","bar")]

Questo non è davvero soddisfacente, però, e non riesco a ricordare la parte superiore della mia testa perché (&&&) comporta in questo modo, con una freccia non deterministico (userei personalmente il proc/do notazione per qualcosa di molto più complicato di questo).


UPDATE: Sembra che ci sia qualcosa di strano sta succedendo qui con runLA e xread. Se si utilizza runX e readString tutto funziona come previsto:

> let xml = "<root><a>foo</a><b>bar</b><c>baz</c></root>"
> let parse p = runX (readString [] xml >>> p)
> let extract' s = getChildren >>> hasName s >>> getChildren >>> getText
> parse (getChildren >>> isElem >>> (extract' "a" &&& extract' "b"))
[("foo","bar")]

Questo significa che è necessario eseguire il parser in monade IO, ma ci sono vantaggi di utilizzare runX comunque (messaggi di meglio di errore, ecc.).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top