首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >getLine懒惰吗?

getLine懒惰吗?
EN

Stack Overflow用户
提问于 2017-08-20 21:36:30
回答 1查看 508关注 0票数 3

getLine懒惰吗?

假设我的输入有很长的线。只是数列而已。我只需要把三个第一个数字相加。getLine是高效的,只读取行的第一部分,还是必须创建自己的懒行读取函数,即逐个读取字符?

如果我总结整个过程,我的实现是否有效?(逐个阅读字符会有开销吗?)

代码语言:javascript
复制
import Control.Applicative

main = do
    line <- getLine'
    print $ sum $ map read $ take 3 $ words line

getLine' :: IO String
getLine' = do
    c <- getChar
    if c == '\n' then return [] else (c:) <$> getLine'
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-09-02 23:11:41

虽然getLine并不懒惰,但getContents是这样的,它可以与lineswords这样的函数组合。因此,下面的程序将只读取stdin的足够多,以便从第一行得到(最多)三个整数,并打印它们的和:

代码语言:javascript
复制
main :: IO ()
main = do contents <- getContents
          let lns = lines contents
              result = sum $ map read $ take 3 $ words $ head lns
          print (result :: Integer)

注意,如果您修改程序以访问后续的行--例如,如果您添加了:

代码语言:javascript
复制
putStrLn $ take 80 $ lns !! 1

在程序底部打印第二行的前80个字符时,程序必须先读取第一行(在程序的最后两行之间挂起一点),然后再处理第二行的前80个字符。换句话说,只有当你只需要读第一行的第一部分,如果这对你来说不是很明显的时候,这个懒行阅读才会有用--哈斯克尔没有任何神奇的方法可以跳过第一行的其余部分进入第二行。

最后,请注意,对于上面的程序,如果在第一行中只有不到三个整数,它只会对这些数字进行求和,并且不会尝试读过第一行(我认为这正是您想要的)。如果您实际上并不关心行尾,只想将文件中的前三个数字相加,而不管它们是如何划分成行的,那么您可以将内容直接分解成这样的单词:

代码语言:javascript
复制
main = do contents <- getContents
          let result = sum $ map read $ take 3 $ words contents
          print (result :: Integer)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45787011

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档