嘿,大家好,我需要一些幫助,我如何使用sum內建函數對文件列表求和?Haskell IO字符串 - >列表
例如: 的text.txt包含[1,2,3,4]
,我想從文件列表和帶有內置的總和總結這些數字。可能嗎?
謝謝!
嘿,大家好,我需要一些幫助,我如何使用sum內建函數對文件列表求和?Haskell IO字符串 - >列表
例如: 的text.txt包含[1,2,3,4]
,我想從文件列表和帶有內置的總和總結這些數字。可能嗎?
謝謝!
當然。
main = do
contents <- readFile "text.txt"
print . sum . read $ contents
這使用從前奏的一些標準功能:
readFile :: FilePath -> IO String
文件讀入一個字符串。
read :: Read a => String -> a
將String
轉換爲Read
類型類型中的任何類型。如果編譯器找不到你想要的類型,你可能需要添加一個類型註釋。在這種情況下,由於我們對結果使用sum
,因此編譯器可以計算出它,因此它推斷a
必須是[Integer]
。 (它實際上推斷出Num a => [a]
,但由於缺省類型,此缺省值爲[Integer]
)。
read
預計在相同類型上由show
生成的格式相同。
注意,我不得不用做表示法來提取IO String
的String
才能申請read
它。
技術上,編譯器猜測你想要哪種類型(通過使用默認值),因爲'sum'可以操作多種數字類型。 – 2011-05-11 21:47:09
謝謝!我知道了! – felipefariax 2011-05-11 21:58:12
或只是'main = readFile「text.txt」>> = print.sum.read' – 2011-05-11 22:49:19
如果列表始終處於這種格式,則需要使用read
函數。該功能反序列化數據,即將字符串變成程序數據類型。例如,
Prelude> read "[1, 2, 3, 4]" :: [Int]
[1,2,3,4]
現在,您可以將其與文件IO結合使用,但如果您不熟悉,則需要閱讀Monads。一些好的資源是[Wikipedia]和[http://www.haskell.org/haskellwiki/Monad]。實質上,每個monad將代表順序執行中的一個步驟 - 由於IO修改了環境,所以這是必需的,因此必須確定其執行順序。
我想出了閱讀的代碼,然後總結是:
main = do
fc <- readFile "file1"
parsed <- return (read fc :: [Int])
putStrLn (printf "sum: %d" (sum parsed))
謝謝,雖然它不好,它不理解空格分隔的數字沒有「[」的字符。 – Alehar 2012-07-20 07:55:45
@Alehar如果你沒有大括號,你可以試試'words'函數,去掉尾隨逗號。如果你需要更先進的東西,你可以試試一下Parsec解析器。 – gatoatigrado 2012-07-24 02:40:49
所以,你將不能夠真正得到一個價值:: [Int]
,因爲那將是不安全的。但是我們可以讓你IO [Int]
,然後再傳遞,通過>>=
到print
:
main = (sum . read) `fmap` readFile "myFile" >>= print
如果您使用Control.Applicative
,你可以把它更漂亮:
main = sum . read <$> readFile "myFile" >>= print
瞧!正如你所看到的,這種方式比使用do
-notation更簡潔。do
-notation非常適合擺脫嵌套lambda,但在很多情況下,它並不是必需的。
編輯:@augustss提出以下建議更好的選擇:
main = print . sum . read =<< readFile "myFile"
這是真棒,因爲它更簡單,而且不依賴於Control.Applicative
;更重要的是,它不必閱讀爲「內外」,因爲@hammar指出。
另請參閱[haskell + io](http://stackoverflow.com/questions/tagged/haskell+io)標記中的此常見問題解答。 – 2011-05-11 22:07:32