2011-05-11 65 views
2

嘿,大家好,我需要一些幫助,我如何使用sum內建函數對文件列表求和?Haskell IO字符串 - >列表

例如: 的text.txt包含[1,2,3,4]

,我想從文件列表和帶有內置的總和總結這些數字。可能嗎?

謝謝!

+1

另請參閱[haskell + io](http://stackoverflow.com/questions/tagged/haskell+io)標記中的此常見問題解答。 – 2011-05-11 22:07:32

回答

2

當然。

main = do 
    contents <- readFile "text.txt" 
    print . sum . read $ contents 

這使用從前奏的一些標準功能:

  • readFile :: FilePath -> IO String文件讀入一個字符串。

  • read :: Read a => String -> aString轉換爲Read類型類型中的任何類型。如果編譯器找不到你想要的類型,你可能需要添加一個類型註釋。在這種情況下,由於我們對結果使用sum,因此編譯器可以計算出它,因此它推斷a必須是[Integer]。 (它實際上推斷出Num a => [a],但由於缺省類型,此缺省值爲[Integer])。

    read預計在相同類型上由show生成的格式相同。

注意,我不得不用做表示法來提取IO StringString才能申請read它。

+1

技術上,編譯器猜測你想要哪種類型(通過使用默認值),因爲'sum'可以操作多種數字類型。 – 2011-05-11 21:47:09

+0

謝謝!我知道了! – felipefariax 2011-05-11 21:58:12

+3

或只是'main = readFile「text.txt」>> = print.sum.read' – 2011-05-11 22:49:19

1

如果列表始終處於這種格式,則需要使用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)) 
+0

謝謝,雖然它不好,它不理解空格分隔的數字沒有「[」的字符。 – Alehar 2012-07-20 07:55:45

+1

@Alehar如果你沒有大括號,你可以試試'words'函數,去掉尾隨逗號。如果你需要更先進的東西,你可以試試一下Parsec解析器。 – gatoatigrado 2012-07-24 02:40:49

3

所以,你將不能夠真正得到一個價值:: [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指出。

+4

'main = print。總和。 read =「readFile」myFile「' – augustss 2011-05-11 21:58:45

+0

@augustss哇,這樣更好!謝謝。 – 2011-05-11 22:16:56

+0

從右到左,它也讀得更好,而你必須閱讀適用的「內外」。 – hammar 2011-05-11 22:20:57