Даниэль Вагнер - отличное решение. Вот еще один пример, чтобы вы могли получить больше идей об эффективной обработке файлов.
{-# 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 () - извините, если это слишком много. Я просто имею в виду, что когда вы читаете File, вы не возвращаете ByteString, вы возвращаете ByteString, завернутый в IO и IO (ByteString). <$>
говорит: «Эй, я хочу поработать с вещью внутри IO, а затем снова обернуть ее.
B.split разделяет каждую строку на числа на основе пробела. (Мы могли бы также использовать B.words для этого) Единственная другая интересная часть - это в sumStrs
, который мы используем для деконструкции / сопоставления с образцом, чтобы извлечь первое значение из Just, которое возвращается функцией readInt.
Надеюсь, это было полезно. Спросите, если у вас есть какие-либо вопросы.