mk1*_*k12 5 file-io haskell functional-programming input
我最近做了滑铁卢CCC,我觉得Haskell是回答这些类型问题的完美语言.我还在学习它.不过,我在输入方面有点挣扎.
这是我正在使用的:
import IO
import System.Environment
import System.FilePath
…
main = do
name <- getProgName
args <- getArgs
input <- readFile $
if not (null args)
then head args
else dropExtension name ++ ".in"
let (k:code:_) = lines input
putStrLn $ decode (read k) code
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我正在从命令行给定的文件路径中读取,或者从j1.in例如,如果调用此程序j1.hs并将其编译为j1.
我只对文件的前两行有兴趣,所以我已经使用模式匹配来获取这些线路,并将其绑定到k和code在这个例子.然后我读k作一个整数并将它和代码字符串传递给我decode输出的函数.
我想知道是否readFile将整个文件加载到内存中,这将是不好的.但后来我开始思考,也许是因为Haskell是懒惰的,它只会读取前两行,因为这就是后来要求的全部内容.我对吗?
此外,如果有任何代码示例可能更好或更具惯用性,请告诉我.
在对文件readFile说:
该
readFile函数读取文件并以字符串形式返回文件的内容.根据需要,懒惰地读取文件,如同getContents.
所以是的,它只会读取文件的前两行(缓冲意味着它可能会在幕后读取更多).但这是一个readFile特别的属性,而不是一般的所有Haskell I/O函数.
懒惰的I/O对于I/O繁重的程序(例如web服务器)来说是一个坏主意,但它对于没有做太多I/O的简单程序很有效.
是的,readFile很懒.如果你想明确它,你可以使用:
import Control.Monad (replicateM)
import System.IO
readLines n f = withFile f ReadMode $ replicateM n . hGetLine
-- in main
(k:code:_) <- readLines 2 filename
Run Code Online (Sandbox Code Playgroud)
这将确保文件尽快关闭.
但你做的方式很好.