2012-01-04 17 views
6

Estoy trabajando en el análisis de un archivo CSV en un tipo CSV que es una lista de registros que es una lista de campos, que son solo cadenas. Después de insertar una nueva fila y luego intentar acceder al csv obtengo el error de desbordamiento de c stack. He leído que este error puede provenir de un "thunk" demasiado grande al usar la recursividad de la cola, pero no creo que eso sea lo que estoy haciendo mal."ERROR - Desbordamiento de pila C" en Haskell usando los abrazos

type CSV = [Record] 
type Record = [Field] 
type Field = String 

run :: IO() 
run = 
do 
    inFile <- readFile "myFile.csv" 
    let csv = parse inFile 
    let csv = (insertRow "abc,def,ghi" csv) 
    putStr (show csv) 

insertRow :: String -> CSV -> CSV 
insertRow newRow csv = csv ++ [toRecord newRow] 

parse :: String -> CSV 
parse file = map toRecord (parseLines file "" []) 

toRecord :: String -> Record 
toRecord line = parseWords line "" [] 

-- parseLine input partialCSV records 
parseLines :: String -> String -> [String] -> [String] 
parseLines [] partial records = records ++ [partial] 
parseLines ('\r':xs) partial records = parseLines xs [] (records ++ [partial]) 
parseLines (x:xs) partial records = parseLines xs (partial ++ [x]) records 

-- parseWords input partialRecord fields 
parseWords :: String -> String -> [String] -> [String] 
parseWords [] partial fields = fields ++ [partial] 
parseWords ('"':xs) partial fields = parseQuotes xs partial fields 
parseWords (',':xs) partial fields = parseWords xs [] (fields ++ [partial]) 
parseWords (x:xs) partial fields = parseWords xs (partial ++ [x]) fields 

parseQuotes :: String -> String -> [String] -> [String] 
parseQuotes ('"':xs) partial fields = parseWords xs [] (fields ++ [partial]) 
parseQuotes (x:xs) partial fields = parseQuotes xs (partial ++ [x]) fields 
+5

Sin relación con su problema, la última versión de abrazos tiene más de cinco años. El lenguaje evoluciona aún más, también ghci tiene un mejor rendimiento (y viene con un compilador;). Aunque es triste, recomiendo no seguir abrazando (hasta que alguien lo reviva). –

Respuesta

2

El doble let csv = ... parece sospechoso. ¿Podría intentar desenredar las dos variables? Probablemente no haga lo que quiera (en Haskell let es recursivo).

+0

Gracias por la respuesta rápida, combiné las dos letras en una línea y ¡funcionó! – user1130083

5

fijaciones vamos son recursivas, por lo que esta línea

let csv = (insertRow "abc,def,ghi" csv) 

crea un bucle infinito, que está definiendo csv en términos de sí mismo de una manera que no ponga fin. Cámbielo a

let csv' = ... 

e imprime csv' en la siguiente línea.

+0

¡Gracias por la respuesta rápida y útil! Aunque no estoy completamente seguro sobre el let. ¿Esto significa que no puedo cambiar csv, tengo que seguir usando csv ', csv' '...? – user1130083

+2

En Haskell, todos los valores son inmutables, por lo que no puede cambiar csv de todos modos. Por lo general, debe dar nuevos nombres a los valores que obtiene como resultado de una 'modificación'. Sin embargo, puede reutilizar nombres sombreando el nombre, pero eso solo funciona si el nombre oculto/rebote no aparece en el RHS de su enlace, de lo contrario, la aparición en el RHS se referiría al nuevo nombre, loop. Puedes tener 'do {blah; let {x = foo; }; let {y = bar x; }; let {x = baz y; }; quux x; } 'y el segundo enlace de' x' sombrearía el primero. Pero no (en general) 'let x = foo x', eso bucles. –

+2

Y dicho sombreado está * muy * desaconsejado. Entonces ... pretenda que no puede hacerlo, y solo use nombres únicos en let anidados (cuando sea razonable). –

Cuestiones relacionadas