2012-01-04 18 views
6

CSVファイルをCSV形式に解析しています.CSV形式はRecordのリストで、Fieldのリストです。新しい行を挿入した後、csvにアクセスしようとすると、Cのスタックオーバーフローエラーが発生します。私はこのエラーを読んで、尾の再帰を使用することによってあまりにも大きな "サンク"から来るかもしれないが、私は間違っていることをthatsとは思わない?HaskellのHaskellで "ERROR-C stack overflow"が発生しました

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

あなたの問題とは無関係に、ハグの最後のリリースは5歳以上です。言語はさらに進化し、ghciのパフォーマンスも向上します(そしてコンパイラも付属しています)。悲しいですが、私はもうハグを使わないことを勧めます(誰かがそれを復活させるまで)。 –

答えて

2

ダブルlet csv = ...が疑わしいと思われます。あなたは2つの変数を解き放つことができますか?おそらくあなたが望むことをしないでしょう(Haskellでletが再帰的です)。

+0

クイック返信をいただきありがとうございました。私は2つを1つの回線に組み合わせて動作させました! – user1130083

5

のlet束縛は再帰的であるので、このライン

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

は、あなたが終了しないように、自身の観点でcsvを定義している、無限ループを作成します。

let csv' = ... 

に変更し、csv'を次の行に変更してください。

+0

すばやく便利な返信をありがとう!私はレットについては完全にはわかりませんが。これは私がcsvを変更できないことを意味しますか、私はcsv '、csv' '...を使用し続ける必要がありますか? – user1130083

+2

ハスケルでは、すべての値が不変なので、とにかくcsvを変更することはできません。だから一般的には、あなたは '変更'の結果として得た値に新しい名前を付ける必要があります。しかし、名前を_shadowing_することによって名前を再利用することはできますが、シャドー/リバウンド名がバインディングのRHSに表示されない場合にのみ機能します。そうでない場合、RHSのオカレンスは新しい名前loopを参照します。あなたは 'do {blah; let {x = foo; }; let {y = bar x; }; let {x = baz y; }; quux x; } 'の第2の束縛は最初の影になります。しかし、(一般的に) 'let x = foo x'ではなく、ループします。 –

+2

そしてそのようなシャドウイングは非常に落胆します。だから...あなたはそれをすることができないようなふりをし、ネストした缶の中でユニークな名前を使用するだけです(合理的なところでは)。 –

関連する問題