[英]Haskell file reading
我最近才開始學習 Haskell,在試圖弄清楚文件讀取的工作原理時遇到了很多麻煩。
例如,我有一個包含數字行的文本文件“test.txt”:
32 4
2 30
300 5
我想閱讀每一行,然后評估每個單詞並添加它們。
因此,我正在嘗試做這樣的事情:
import System.IO
import Control.Monad
main = do
let list = []
handle <- openFile "test.txt" ReadMode
contents <- hGetContents handle
singlewords <- (words contents)
list <- f singlewords
print list
hClose handle
f :: [String] -> [Int]
f = map read
我知道這是完全錯誤的,但我根本不知道如何正確使用語法。
任何幫助將不勝感激,以及鏈接到具有除例子和代碼解釋好的教程,這個我已經充分閱讀。
不錯的開始! 唯一要記住的是純函數應用程序應該使用let
而不是綁定<-
。
import System.IO
import Control.Monad
main = do
let list = []
handle <- openFile "test.txt" ReadMode
contents <- hGetContents handle
let singlewords = words contents
list = f singlewords
print list
hClose handle
f :: [String] -> [Int]
f = map read
這是使事物編譯和運行所需的最小更改。 在風格上,我有幾點評論:
list
兩次看起來有點陰暗。 請注意,這並沒有改變值list
——而是隱藏了舊定義。readFile
比手動打開、讀取和關閉文件更可取。實現這些更改給出了這樣的東西:
main = do
contents <- readFile "test.txt"
print . map readInt . words $ contents
-- alternately, main = print . map readInt . words =<< readFile "test.txt"
readInt :: String -> Int
readInt = read
Daniel Wagner 的解決方案是一個很好的解決方案。 這是它的另一個擺動,因此您可以獲得有關有效文件處理的更多想法。
{-# LANGUAGE OverloadedStrings #-}
import System.IO
import qualified Data.ByteString.Lazy.Char8 as B
import Control.Applicative
import Data.List
sumNums :: B.ByteString -> Int
sumNums s = foldl' sumStrs 0 $ B.split ' ' s
sumStrs :: Int -> B.ByteString -> Int
sumStrs m i = m+int
where Just(int,_) = B.readInt i
main = do
sums <- map sumNums <$> B.lines <$> B.readFile "testy"
print sums
首先,您將看到 OverloadedStrings 編譯指示。 這允許使用僅對實際上是字節串的字符串文字使用普通引號。 出於多種原因,我們將使用 Lazy ByteStrings 來處理文件。 首先,它允許我們通過程序流式傳輸文件,而不是一次強制將其全部放入內存中。 此外,字節串通常比字符串更快、更高效。
其他一切都非常簡單。 我們將文件讀入一個懶惰的行列表,然后在每一行上映射一個求和函數。 <$>
只是允許我們對 IO() 函子內部的值進行操作的快捷方式——如果這太過分了,我深表歉意。 我的意思是,當你讀取文件時,你不會得到一個 ByteString,你會得到一個包裹在 IO 和 IO(ByteString) 中的 ByteString。 <$>
表示“嘿”我想對 IO 內部的東西進行操作,然后將其包裝回去。
B.split 根據空格將每一行分成數字。 (我們也可以為此使用 B.words)唯一有趣的部分是在sumStrs
我們使用解構/模式匹配從 readInt 函數返回的 Just 中提取第一個值。
我希望這可以幫到你。 詢問您是否有任何問題。
對於所有非功能性程序員來說,這里是一種享受
unsafePerformIO . readFile $ "file.txt"
將文件讀入字符串
沒有 IO 字符串,只是一個普通的滿載字符串可供使用。 這可能不是正確的方法,但它有效,無需更改現有函數以適應 IO String
ps 不要忘記導入
import System.IO.Unsafe
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.