2011-05-11 61 views
2

嘿,大家好,我需要一些帮助,我如何使用sum内建函数对文件列表求和?Haskell IO字符串 - >列表

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

,我想从文件列表和带有内置的总和总结这些数字。可能吗?

谢谢!

+1

另请参阅[haskell + io](http://stackoverflow.com/questions/tagged/haskell+io)标记中的此常见问题解答。 – 2011-05-11 22:07:32

回答

2

当然。

main = do 
    contents <- readFile "text.txt" 
    print . sum . read $ contents 

这使用从前奏的一些标准功能:

  • readFile :: FilePath -> IO String文件读入一个字符串。

  • read :: Read a => String -> aString转换为Read类型类型中的任何类型。如果编译器找不到你想要的类型,你可能需要添加一个类型注释。在这种情况下,由于我们对结果使用sum,因此编译器可以计算出它,因此它推断a必须是[Integer]。 (它实际上推断出Num a => [a],但由于缺省类型,此缺省值为[Integer])。

    read预计在相同类型上由show生成的格式相同。

注意,我不得不用做表示法来提取IO StringString才能申请read它。

+1

技术上,编译器猜测你想要哪种类型(通过使用默认值),因为'sum'可以操作多种数字类型。 – 2011-05-11 21:47:09

+0

谢谢!我知道了! – felipefariax 2011-05-11 21:58:12

+3

或只是'main = readFile“text.txt”>> = print.sum.read' – 2011-05-11 22:49:19

1

如果列表始终处于这种格式,则需要使用read函数。该功能反序列化数据,即将字符串变成程序数据类型。例如,

Prelude> read "[1, 2, 3, 4]" :: [Int] 
[1,2,3,4] 

现在,您可以将其与文件IO结合使用,但如果您不熟悉,则需要阅读Monads。一些好的资源是[Wikipedia]和[http://www.haskell.org/haskellwiki/Monad]。实质上,每个monad将代表顺序执行中的一个步骤 - 由于IO修改了环境,所以这是必需的,因此必须确定其执行顺序。

我想出了阅读的代码,然后总结是:

main = do 
    fc <- readFile "file1" 
    parsed <- return (read fc :: [Int]) 
    putStrLn (printf "sum: %d" (sum parsed)) 
+0

谢谢,虽然它不好,它不理解空格分隔的数字没有“[”的字符。 – Alehar 2012-07-20 07:55:45

+1

@Alehar如果你没有大括号,你可以试试'words'函数,去掉尾随逗号。如果你需要更先进的东西,你可以试试一下Parsec解析器。 – gatoatigrado 2012-07-24 02:40:49

3

所以,你将不能够真正得到一个价值:: [Int],因为那将是不安全的。但是我们可以让你IO [Int],然后再传递,通过>>=print

main = (sum . read) `fmap` readFile "myFile" >>= print 

如果您使用Control.Applicative,你可以把它更漂亮:

main = sum . read <$> readFile "myFile" >>= print 

瞧!正如你所看到的,这种方式比使用do -notation更简洁。do -notation非常适合摆脱嵌套lambda,但在很多情况下,它并不是必需的。

编辑:@augustss提出以下建议更好的选择:

main = print . sum . read =<< readFile "myFile" 

这是真棒,因为它更简单,而且不依赖于Control.Applicative;更重要的是,它不必阅读为“内外”,因为@hammar指出。

+4

'main = print。总和。 read =“readFile”myFile“' – augustss 2011-05-11 21:58:45

+0

@augustss哇,这样更好!谢谢。 – 2011-05-11 22:16:56

+0

从右到左,它也读得更好,而你必须阅读适用的“内外”。 – hammar 2011-05-11 22:20:57