嘿伙计们,我需要一些帮助,如何使用sum builtin函数从文件中汇总一个列表?
例如: text.txt包含[1,2,3,4]
我希望从文件中获取此列表,并将这些数字与内置总和相加。有可能吗?
谢谢!
答案 0 :(得分:3)
因此,您将无法实际获得值:: [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 指出的那样。
答案 1 :(得分:2)
不确定
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从String
中提取IO String
才能将read
应用于此{{1}}。
答案 2 :(得分:1)
如果列表始终采用这种格式,则需要使用read
功能。此函数反序列化数据,即将字符串转换为程序数据类型。例如,
Prelude> read "[1, 2, 3, 4]" :: [Int]
[1,2,3,4]
现在,您可以将其与文件IO结合使用,但如果您不熟悉,则需要阅读Monads。一些好的资源是[http://www.haskell.org/haskellwiki/Monad]和维基百科。从本质上讲,每个monad将代表顺序执行中的一个步骤 - 这是必要的,因为IO修改了环境,因此必须确定其执行顺序。
我提出的阅读和总结的代码是:
main = do
fc <- readFile "file1"
parsed <- return (read fc :: [Int])
putStrLn (printf "sum: %d" (sum parsed))