gpt4 book ai didi

haskell - getLine 是懒惰的吗?

转载 作者:行者123 更新时间:2023-12-02 16:07:23 24 4
gpt4 key购买 nike

getLine 是懒惰的吗?

假设我的输入有很长的一行。这只是一个数字序列。我只需要对前 3 个数字求和。 getLine 是否高效并且只读取该行的第一部分,或者我是否必须创建自己的函数来进行惰性行读取,以便一个一个地读取字符?

如果我对整行求和,我的实现会高效吗? (会不会因为逐个读取字符而产生开销?)

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'

最佳答案

同时getLine不懒,getContents是,并且它可以与 lines 等函数结合使用和words 。因此,以下程序将仅读取足够的标准输入以从第一行获取(最多)三个整数并打印它们的总和:

main :: IO ()
main = do contents <- getContents
let lns = lines contents
result = sum $ map read $ take 3 $ words $ head lns
print (result :: Integer)

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

putStrLn $ take 80 $ lns !! 1

到程序底部打印第二行的前 80 个字符,然后程序必须在处理之前完成第一行的读取(因此会在程序的最后两行之间挂起一段时间)第二个的前 80 个字符。换句话说,这种懒惰的行读取仅在您需要读取第一行的第一位时有用,如果这对您来说并不明显 - Haskell 没有任何神奇的方法跳过第一行的其余部分进入第二行。

最后,请注意,对于上面的程序,如果第一行上的整数少于三个,它只会将这些数字相加,并且不会尝试读取第一行之后的内容(我认为这就是您要执行的操作)通缉)。如果您实际上并不关心行结尾,而只想对文件中的前三个数字求和,无论它们如何划分为行,那么您可以将内容直接分解为单词,如下所示:

main = do contents <- getContents
let result = sum $ map read $ take 3 $ words contents
print (result :: Integer)

关于haskell - getLine 是懒惰的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45787011/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com