tuplas sobre opciones hacer funciones funcion ficheros ejemplos drop como ciclos xml haskell xml-parsing monads arrows

xml - sobre - Dar parámetros a la función de flecha en Haskell



if en haskell ejemplos (1)

Tengo un archivo XML con algunos datos. Este archivo tiene una descripción de las columnas y los datos en sí. Puedo leer los nombres de las columnas, pero no puedo leer los datos porque no entiendo cómo asignar los nombres de estas a una función que devolverá los datos.

Archivo XML:

<?xml version="1.0" encoding="UTF-8"?> <Document> <Header> <Project code="SOME PROJECT" label="PROJECT LABEL"></Project> <Datatable name="LOG" label="Visits"></Datatable> <Columns> <column name="study" label="Study" ordinal="1" type="TEXT"></column> <column name="site" label="Site" ordinal="2" type="INTEGER"></column> <column name="number" label="Subject" ordinal="3" type="INTEGER"></column> <column name="visit" label="Visit number" ordinal="4" type="CHARACTER VARYING(20)"> </column> <column name="vdate" label="Visit date (dd/mm/yyyy)." ordinal="5" type="CHARACTER VARYING(10)"></column> </Columns> </Header> <table xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <row> <study>Some study</study> <site>1</site> <number>1</number> <visit>1</visit> <vdate>28/12/2010</vdate> </row> <row> <study>Some study</study> <site>1</site> <number>1</number> <visit>2</visit> <vdate>03/03/2011</vdate> </row> <row> <study>Some study</study> <site>1</site> <number>1</number> <visit>3</visit> <vdate>09/06/2011</vdate> </row> </table> </Document>

Código de muestra:

{-# LANGUAGE Arrows #-} import Text.XML.HXT.Core import Data.Tree.NTree.TypeDefs parseXML :: String -> IOStateArrow s b XmlTree parseXML file = readDocument [ withValidate yes , withRemoveWS yes ] file atTag :: ArrowXml a => String -> a (NTree XNode) XmlTree atTag tag = deep (isElem >>> hasName tag) text :: ArrowXml cat => cat (NTree XNode) String text = getChildren >>> getText getRowsData :: ArrowXml cat => cat (NTree XNode) [String] getRowsData = atTag "table" >>> proc l -> do row <- atTag "row" -< l study <- text <<< atTag "study" -< row site <- text <<< atTag "site" -< row returnA -< [study,site] readTable :: ArrowXml t => t (NTree XNode) [[String]] readTable = proc l -> do rows <- listA getRowsData -< l returnA -< rows main :: IO () main = do res <- runX ( parseXML "log.xml" >>> readTable ) print res

El problema para mí está en getRowsData . En el código de ejemplo, di los nombres de las columnas de forma implícita, pero quiero que se lean de una lista, se apliquen en la función de flecha y vuelvan las filas.


import Control.Arrow

Combinación de listas de flechas

Creo que lo que estás buscando es una forma de combinar varias flechas en la misma entrada para mostrar su resultado:

list :: Arrow a => [a b c] -> a b [c] list [] = returnA >>^ const [] list (a:as) = (a &&& list as) >>^ uncurry (:)

(a &&& list as) devuelve un par de la cabeza y la cola, luego aplicamos >>^ la función pura uncurry (:) :: (x,[x]) -> [x] para recombinarlos.

Vamos a probarlo. Aquí hay algunas cosas para jugar con las flechas IO. Una mónada es una flecha, pero debes envolverla en su categoría Kleisli. runKleisli desenvuelve de nuevo para que pueda ejecutarlo, pero me lleva demasiado tiempo escribir, así que he usado una versión infijo >$> para alimentarlo con la entrada:

ask :: Kleisli IO String String ask = Kleisli $ /xs -> putStrLn xs >> getLine (>$>) = runKleisli

Entonces ahora es más fácil interactuar:

*Main> ask >$> "Hello?" Hello? Hello! "Hello!"

y la list funciona bien:

*Main> list [ask,ask] >$> "say something!" say something! OK say something! What do you want me to say? ["OK","What do you want me to say?"]

De [String] a la flecha que devuelve [String]

Pero desea convertir una lista de cadenas en una flecha que produce listas de cadenas.

appList :: Arrow a => (s -> a b c) -> [s] -> a b [c] appList f xs = list (map f xs)

Podemos probar eso con una variante en la prueba de pregunta:

askRespond xs = Kleisli $ /thx -> do putStrLn xs ans <- getLine putStrLn thx return ans

Así que podemos ver que appList está funcionando de la manera que desea, al hacer una flecha de cada cadena y ejecutar cada una, combinando las respuestas en una cadena de nuevo:

*Main> appList askRespond ["What''s your name?","What''s your favourite colour?","Would you like some cheese?"] >$> "Thanks." What''s your name? Andrew Thanks. What''s your favourite colour? Green Thanks. Would you like some cheese? Yes - could I have gruyere? Thanks. ["Andrew","Green","Yes - could I have gruyere?"]

Agarrando múltiples contenidos de etiquetas

Ahora apliquemos eso a su problema.

Primero, hagamos una taquigrafía para hacer una flecha de una cuerda:

textAtTag xs = text <<< atTag xs

Entonces usemos la appList :

getRowsData = atTag "table" >>> atTag "row" >>> appList textAtTag ["study","site"]

No he probado ese último, ¡por favor revisa!