Dus*_*nny 27 haskell words file
我刚刚开始学习Haskell,我在尝试弄清楚文件读取的工作方式时遇到了很多麻烦.
例如,我有一个文本文件"test.txt"它包含数字行,例如:
32 4
2 30
300 5
Run Code Online (Sandbox Code Playgroud)
我想阅读每一行,然后评估每个单词并添加它们.因此,我到目前为止尝试做这样的事情:
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
Run Code Online (Sandbox Code Playgroud)
我知道这是完全错误的,但我根本不知道如何正确使用语法.任何帮助将不胜感激.除了这个代码的示例和解释之外的好教程的链接:http: //learnyouahaskell.com/input-and-output我已经完全阅读了它
Dan*_*ner 55
不错的开始!唯一要记住的是纯函数应用程序应该使用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
Run Code Online (Sandbox Code Playgroud)
这是使事物编译和运行所需的最小变化.在风格上,我有一些评论:
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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
首先,您将看到OverloadedStrings编译指示.这允许使用实际上是字节串的字符串文字的常规引号.我们将使用Lazy ByteStrings处理文件有几个原因.首先,它允许我们通过程序流式传输文件,而不是一次性将其全部压入内存.此外,字节串通常比字符串更快,更有效.
其他一切都非常简单.我们将文件文件归待为一个懒惰的行列表,然后在每一行上映射求和函数.这<$>只是允许我们操作IO()仿函数内部值的快捷方式 - 如果这太多了,我道歉.我只是说当你readFile你没有得到一个ByteString时,你得到一个包含在IO中的ByteString IO(ByteString).该<$>说"嗨"我想在IO里面的东西进行操作,然后把它包备份.
B.split根据空格将每一行分成数字.(我们也可以使用B.words这个)唯一另一个有趣的部分是sumStrs我们使用解构/模式匹配来提取readInt函数返回的Just的第一个值.
我希望这可以帮到你.问你是否有任何问题.
| 归档时间: |
|
| 查看次数: |
36157 次 |
| 最近记录: |