嘿,大家好,我需要一些帮助,我如何使用sum内建函数对文件列表求和?Haskell IO字符串 - >列表
例如: 的text.txt包含[1,2,3,4]
,我想从文件列表和带有内置的总和总结这些数字。可能吗?
谢谢!
嘿,大家好,我需要一些帮助,我如何使用sum内建函数对文件列表求和?Haskell IO字符串 - >列表
例如: 的text.txt包含[1,2,3,4]
,我想从文件列表和带有内置的总和总结这些数字。可能吗?
谢谢!
当然。
main = do
contents <- readFile "text.txt"
print . sum . read $ contents
这使用从前奏的一些标准功能:
readFile :: FilePath -> IO String
文件读入一个字符串。
read :: Read a => String -> a
将String
转换为Read
类型类型中的任何类型。如果编译器找不到你想要的类型,你可能需要添加一个类型注释。在这种情况下,由于我们对结果使用sum
,因此编译器可以计算出它,因此它推断a
必须是[Integer]
。 (它实际上推断出Num a => [a]
,但由于缺省类型,此缺省值为[Integer]
)。
read
预计在相同类型上由show
生成的格式相同。
注意,我不得不用做表示法来提取IO String
的String
才能申请read
它。
技术上,编译器猜测你想要哪种类型(通过使用默认值),因为'sum'可以操作多种数字类型。 – 2011-05-11 21:47:09
谢谢!我知道了! – felipefariax 2011-05-11 21:58:12
或只是'main = readFile“text.txt”>> = print.sum.read' – 2011-05-11 22:49:19
如果列表始终处于这种格式,则需要使用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))
谢谢,虽然它不好,它不理解空格分隔的数字没有“[”的字符。 – Alehar 2012-07-20 07:55:45
@Alehar如果你没有大括号,你可以试试'words'函数,去掉尾随逗号。如果你需要更先进的东西,你可以试试一下Parsec解析器。 – gatoatigrado 2012-07-24 02:40:49
所以,你将不能够真正得到一个价值:: [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指出。
另请参阅[haskell + io](http://stackoverflow.com/questions/tagged/haskell+io)标记中的此常见问题解答。 – 2011-05-11 22:07:32