Haskell IO String - >名单

时间:2011-05-11 21:36:48

标签: haskell io

嘿伙计们,我需要一些帮助,如何使用sum builtin函数从文件中汇总一个列表?

例如: text.txt包含[1,2,3,4]

我希望从文件中获取此列表,并将这些数字与内置总和相加。有可能吗?

谢谢!

3 个答案:

答案 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 -> aString转换为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))