6

私はCSVファイルを解析して、フィールドのリストであるレコードのリストであるCSVタイプに変換しようとしています。これは単なる文字列です。新しい行を挿入して csv にアクセスしようとすると、c スタック オーバーフロー エラーが発生します。このエラーは、末尾再帰を使用して「サンク」が大きすぎるために発生する可能性があることを読みましたが、それが間違っているとは思いませんか?

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
4

2 に答える 2

5

let バインディングは再帰的であるため、この行

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

無限ループを作成しcsvます。終了しない方法でそれ自体に関して定義しています。に変更します

let csv' = ...

csv'次の行に出力します。

于 2012-01-04T14:30:25.127 に答える
2

ダブルlet csv = ...は疑わしいようです。2 つの変数のもつれをほどいてみていただけますか? それはおそらくあなたが望むことをしません(Haskellletでは再帰的です)。

于 2012-01-04T14:29:23.873 に答える