[英]Haskell IO String -> List
Hey guys, I need some help, how can I sum a list from a file using the sum builtin function? 大家好,我需要一些帮助,如何使用内建的sum函数对文件列表进行求和?
example: text.txt contains [1,2,3,4] 例如:text.txt包含[1,2,3,4]
and i want to get this list from the file and sum these numbers with the sum builtin. 我想从文件中获取此列表,并将这些数字与内置的总和相加。 Is it possible?
可能吗?
Thanks! 谢谢!
So, you won't be able to actually get a value :: [Int]
, because that would be unsafe. 因此,您将无法实际获得值
:: [Int]
,因为那是不安全的。 But we can get you to IO [Int]
, and then pass that through >>=
into print
: 但是我们可以将您带到
IO [Int]
,然后将其通过>>=
传递给print
:
main = (sum . read) `fmap` readFile "myFile" >>= print
If you're using Control.Applicative
, you can make it even prettier: 如果您使用
Control.Applicative
,则可以使其更漂亮:
main = sum . read <$> readFile "myFile" >>= print
Voilà! 瞧! As you can see, this way is much more succinct than using
do
-notation. 如您所见,这种方式比使用
do
-notation简洁得多。 do
-notation is awesome for getting rid of nested lambdas, but in a lot of cases, it's really not necessary. do
notation对于消除嵌套的lambda很棒,但是在很多情况下,这实际上不是必需的。
Edit: @augustss suggests the following superior alternative: 编辑: @augustss建议以下替代方法:
main = print . sum . read =<< readFile "myFile"
This is awesome, in that it's simpler, and doesn't depend on Control.Applicative
; 这很棒,因为它更简单,并且不依赖于
Control.Applicative
; even more importantly, it doesn't have to read be read "inside-out", as @hammar points out. 更重要的是, @ hammar指出,它不必读成“由内而外”。
Sure. 当然。
main = do
contents <- readFile "text.txt"
print . sum . read $ contents
This uses some standard functions from the Prelude: 这使用了Prelude中的一些标准功能:
readFile :: FilePath -> IO String
reads the file into a string. readFile :: FilePath -> IO String
将文件读取为字符串。
read :: Read a => String -> a
converts from a String
to any type in the Read
typeclass. read :: Read a => String -> a
从String
转换为Read
类型类中的任何类型。 You might have to add a type annotation if the compiler couldn't figure out which type you wanted. 如果编译器无法确定所需的类型,则可能必须添加类型注释。 In this case the compiler can figure it out since we used
sum
on the result, so it infers that a
must be [Integer]
. 在这种情况下,由于我们在结果上使用了
sum
,因此编译器可以弄清楚,因此它推断a
必须为[Integer]
。 (It actually infers Num a => [a]
, but this defaults to [Integer]
due to type defaulting). (它实际上推断
Num a => [a]
,但是由于类型默认值,它默认为[Integer]
)。
read
expects the same format generated by show
on the same type. read
期望使用相同类型的show
生成相同的格式。
Note that I had to use do-notation to extract the String
from IO String
in order to apply read
to it. 请注意,我不得不用做标记法提取
String
从IO String
才能申请read
它。
If the list is always in this kind of format, you want to use the read
function. 如果列表始终采用这种格式,则要使用
read
功能。 This function deserializes data, ie turns a string into a program data type. 该函数反序列化数据,即将字符串转换为程序数据类型。 For example,
例如,
Prelude> read "[1, 2, 3, 4]" :: [Int]
[1,2,3,4]
Now, you can combine this with file IO, but you'll need to read up on Monads if you're not familiar. 现在,您可以将其与文件IO结合使用,但是如果您不熟悉,则需要阅读Monad。 Some good resources are [ http://www.haskell.org/haskellwiki/Monad ] and Wikipedia.
一些很好的资源是[ http://www.haskell.org/haskellwiki/Monad ]和Wikipedia。 Essentially, each monad will represent a step in a sequential execution -- which is necessary since IO modifies the environment, hence its execution order must be determined.
本质上,每个monad将代表顺序执行中的一个步骤-由于IO会修改环境,因此这是必需的,因此必须确定其执行顺序。
The code I came up with for reading and then summing is: 我想到的用于阅读然后总结的代码是:
main = do
fc <- readFile "file1"
parsed <- return (read fc :: [Int])
putStrLn (printf "sum: %d" (sum parsed))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.