开发者

Haskell IO String -> List

Hey guys, I need some help, how can I sum a list from a file using the sum builtin function?

example: text.txt contains [1,2,3,4]

and i want to get this list from the file and sum the开发者_如何学编程se 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. But we can get you to IO [Int], and then pass that through >>= into print:

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

If you're using Control.Applicative, you can make it even prettier:

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

Voilà! As you can see, this way is much more succinct than using do-notation. do-notation is awesome for getting rid of nested lambdas, but in a lot of cases, it's really not necessary.

Edit: @augustss suggests the following superior alternative:

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

This is awesome, in that it's simpler, and doesn't depend on Control.Applicative; even more importantly, it doesn't have to read be read "inside-out", as @hammar points out.


Sure.

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

This uses some standard functions from the Prelude:

  • readFile :: FilePath -> IO String reads the file into a string.

  • read :: Read a => String -> a converts from a String to any type in the Read typeclass. 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]. (It actually infers Num a => [a], but this defaults to [Integer] due to type defaulting).

    read expects the same format generated by show on the same type.

Note that I had to use do-notation to extract the String from IO String in order to apply read to it.


If the list is always in this kind of format, you want to use the read function. This function deserializes data, i.e. 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. Some good resources are [ http://www.haskell.org/haskellwiki/Monad ] and 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.

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))
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜