大家好,我需要帮助,如何使用sum内置函数从文件中汇总列表?
例如: text.txt 包含 [1,2,3,4]
我想从文件中获取这个列表,并使用sum内置函数汇总这些数字。这可能吗?
谢谢!
:: [Int]
,因为那是不安全的。但我们可以让您获得IO [Int]
,然后通过>>=
传递到print
中:main = (sum . read) `fmap` readFile "myFile" >>= print
Control.Applicative
,您可以让代码更加优美:main = sum . read <$> readFile "myFile" >>= print
看到了吗!如您所见,这种方式比使用 do
表示法更为简洁。虽然使用 do
表示法可以消除嵌套的 Lambda,但在许多情况下其实并非必需。
编辑:@augustss 提供了以下更优秀的替代方案:
main = print . sum . read =<< readFile "myFile"
这很棒,因为它更简单,不依赖于 Control.Applicative
; 更重要的是,它不必像 @hammar 指出的那样被“倒着读”。
main = do
contents <- readFile "text.txt"
print . sum . read $ contents
这里使用了Prelude中的一些标准函数:
readFile :: FilePath -> IO String
读取文件并返回一个字符串。
read :: Read a => String -> a
将String
转换为任何Read
类型类中的类型。如果编译器无法确定所需类型,则可能需要添加类型注释。在此示例中,由于我们对结果使用了sum
,因此编译器可以推断出a
必须是[Integer]
。(实际上它推断出的是Num a => [a]
,但由于类型默认值的缘故,默认为[Integer]
)。
read
期望与同一类型上show
生成的格式相同。
请注意,我必须使用do-notation从IO String
中提取String
以便将其应用于read
。
sum
可以操作多种数值类型。 - Robin Greenread
函数。该函数反序列化数据,即将字符串转换为程序数据类型。例如,Prelude> read "[1, 2, 3, 4]" :: [Int]
[1,2,3,4]
现在,您可以将其与文件IO结合使用,但如果您不熟悉单子(Monads),则需要阅读一些好的资源,例如[http://www.haskell.org/haskellwiki/Monad]和维基百科。本质上,每个单子都代表了顺序执行中的一步--这是必要的,因为IO修改了环境,因此必须确定其执行顺序。
我想出来的用于读取和求和的代码是:
main = do
fc <- readFile "file1"
parsed <- return (read fc :: [Int])
putStrLn (printf "sum: %d" (sum parsed))
words
函数,然后去掉末尾的逗号。如果你需要更高级的功能,你可以尝试使用Parsec解析器。 - gatoatigrado