2012-03-27 8 views
3

ファイルを読み込んでデータをカスタムデータ型に処理する小さなプログラムがあります。ファイルを処理する再帰的タプル関数を持つHas​​kellの難点

cat 10 20 dog 
hamster 12 2 wombat 
monkey 1 9 zebra 
lion 30 60 rhino 
... 

私のプログラムは次のようになります:

main :: IO() 
    main = do 
    contents <- readFile "myfile.xyz" 
    let process = clean contents 
    let f = processFile process 
    print f 

clean :: String -> [[String]] 
clean x = Prelude.map words $ lines x 

processFile :: [[String]] -> [(XyzData)] 
processFile [[a,b,c,d]] = [(XyzData a (read b :: Int) (read c :: Int) d)] 
processFile (x:xs) = processFile xs 

data XyzData = XyzData { animal1 :: String, 
         number1 :: Int, 
         number2 :: Int, 
         animal2 :: String 
         } deriving (Show) 

私の問題はprocessFile機能付きで読み込まれるファイルは、次のようになり、データの行が含まれています。現在のところ、この関数はファイルの最後の行をキャプチャし、それを画面に出力します。私は、この関数のリストでappendを使うのではなく、タプルを使って再帰を実装する方法を混乱させています。私の機能やこの機能の実装を改善する方法を誰にでも教えてください。このプログラムの印刷出力は、

[XyzData {animal1 = "cat", number1 = 10, number2 = 20, animal2 = "dog"}, 
[XyzData {animal1 = "hampster", number1 = 12, number2 = 2, animal2 = "wombat"}, 
[XyzData {animal1 = "monkey", number1 = 1, number2 = 9, animal2 = "zebra"}, 
[XyzData {animal1 = "lion", number1 = 30, number2 = 60, animal2 = "rhino"}] 

です。

+2

ハムスターとは何ですか?何かの冗談ですか? – x13n

+0

修正されました。 – drbunsen

答えて

8

おそらく[[a,b,c,d]]試合だけ正確に4つの要素を持つリストで正確に一つの要素、と示していますあなたの第一のパターン

processFile :: [[String]] -> [(XyzData)] 
processFile ([a,b,c,d]:xs) = (XyzData a (read b :: Int) (read c :: Int) d) : processFile xs 
processFile (x:xs) = processFile xs 
processFile [] = [] 

を意図しました。

+0

ありがとうございました。私は何が間違っているのかを見ます。あなたのソリューションは正しく動作します。 – drbunsen

+3

彼の3行目は、すべての(内側の)リストが '[{{processFile(x:xs)= processFile xs'}と一致しないことを保証します。 –

+1

Riccardoの説明をありがとう、私は今、その行の目的を理解しています。 – drbunsen