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 aString
to any type in theRead
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 usedsum
on the result, so it infers thata
must be[Integer]
. (It actually infersNum a => [a]
, but this defaults to[Integer]
due to type defaulting).read
expects the same format generated byshow
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))
精彩评论