2012-03-27 52 views
3

我有一個小程序讀入文件並將數據處理爲自定義數據類型。讀取該文件包含像這樣的數據線:Haskell在遞歸元組函數中的困難

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和list。任何人都可以告訴我如何解決我的功能和/或更好的實現這個功能?該程序的打印輸出應爲:

[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

什麼是hampster?某種形式的? – x13n 2012-03-28 06:21:35

+0

現在更正了,謝謝你的收穫! – drbunsen 2012-03-28 10:23:46

回答

8

你可能打算

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 [] = [] 

你的第一圖案[[a,b,c,d]]比賽只有一個元素,這與恰好四個元素的列表列出。

+0

非常感謝您的幫助。我明白我做錯了什麼。您的解決方案正確運行另外,我認爲解決方案中的第三行((processFile(x:xs)= processFile xs')是多餘的? – drbunsen 2012-03-27 21:24:18

+3

不是。他的第三行確保所有(內部)列表不與[ a,b,c,d]'(即沒有四個元素的元素)將被忽略,並且處理繼續執行下一行文件。 – 2012-03-27 21:27:07

+1

感謝Riccardo的解釋,我現在明白了這一行的目的。 – drbunsen 2012-03-27 21:32:11