[英]Haskell IO String -> List
大家好,我需要一些帮助,如何使用内建的sum函数对文件列表进行求和?
例如:text.txt包含[1,2,3,4]
我想从文件中获取此列表,并将这些数字与内置的总和相加。 可能吗?
谢谢!
因此,您将无法实际获得值:: [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指出,它不必读成“由内而外”。
当然。
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
生成相同的格式。
请注意,我不得不用做标记法提取String
从IO String
才能申请read
它。
如果列表始终采用这种格式,则要使用read
功能。 该函数反序列化数据,即将字符串转换为程序数据类型。 例如,
Prelude> read "[1, 2, 3, 4]" :: [Int]
[1,2,3,4]
现在,您可以将其与文件IO结合使用,但是如果您不熟悉,则需要阅读Monad。 一些很好的资源是[ http://www.haskell.org/haskellwiki/Monad ]和Wikipedia。 本质上,每个monad将代表顺序执行中的一个步骤-由于IO会修改环境,因此这是必需的,因此必须确定其执行顺序。
我想到的用于阅读然后总结的代码是:
main = do
fc <- readFile "file1"
parsed <- return (read fc :: [Int])
putStrLn (printf "sum: %d" (sum parsed))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.