Using IO values for computations
Hi All, I'm writing a code, where the input is read from a text file using: readValues = readFile "Input.txt" Since the type of this is 'IO String', I can't use this in the consequent functions. For an example: I want to split this as follows within another function extractInput url method template | isURI url == True = getList values components | otherwise = [] where components = splitTemplate readValues values = getURL (splitURL url) method This gives the following error: Couldn't match type ‘IO String’ with ‘[Char]’ Expected type: String Actual type: IO String How can I solve this? Thanks in advance! -- Regards, Dananji Liyanage
On 25 May 2015 at 08:44, Dananji Liyanage <dan9131@gmail.com> wrote:
Hi All,
I'm writing a code, where the input is read from a text file using: readValues = readFile "Input.txt"
Since the type of this is 'IO String', I can't use this in the consequent functions.
For an example: I want to split this as follows within another function
extractInput url method template | isURI url == True = getList values components | otherwise = [] where components = splitTemplate readValues values = getURL (splitURL url) method
This gives the following error:
Couldn't match type ‘IO String’ with ‘[Char]’ Expected type: String Actual type: IO String
How can I solve this?
Start with reading some basic Haskell book/tutorial. That should tell you how to e.g. use 'do' notation, or `liftM`, to achieve what you want. /M -- Magnus Therning OpenPGP: 0xAB4DFBA4 email: magnus@therning.org jabber: magnus@therning.org twitter: magthe http://therning.org/magnus
When you do computations involving IO, you want to be in IO context. For instance, let's say we want to count the amount of rows in a file, and we're going to use readFile for this First, lets look at the types readFile :: FilePath -> IO String This is a computation with an IO result, which means we should only access it by IO actions. computeLines :: String -> Int computeLines = length . lines Lines is an example computation for calculating the amount of lines in a file. It's composed of the function lines :: String -> [String] which splits a string into a list of strings, divided by line break. This is the function we want to use the result of readFile on, but as it's IO, the type system won't let us. However, there's hope still countLines :: FilePath -> IO Int countLines fp = do file <- readFile fp return $ computeLines file By the powers of the do notation and IO actions we can compose the functions and still live in the comfortable context of IO actions. If you're not used to IO computations, this snippet will contain some concepts that probably are new to you: * The "do" notation; it's a syntactic sugar for doing sequential computations within a type, like IO actions. * The left pointing arrow (<-) is a type-safe way to extract a contextual value (like IO String) into a computable value (like String). * return packages a computation (like Int) into a contextual value (like IO Int). So what we do is fetching the result from readFile with <-, computes it (computeLines file) and package it from an Int to an IO Int. Best regards, Jonathan 2015-05-25 14:29 GMT+02:00 Magnus Therning <magnus@therning.org>:
On 25 May 2015 at 08:44, Dananji Liyanage <dan9131@gmail.com> wrote:
Hi All,
I'm writing a code, where the input is read from a text file using: readValues = readFile "Input.txt"
Since the type of this is 'IO String', I can't use this in the consequent functions.
For an example: I want to split this as follows within another function
extractInput url method template | isURI url == True = getList values components | otherwise = [] where components = splitTemplate readValues values = getURL (splitURL url) method
This gives the following error:
Couldn't match type ‘IO String’ with ‘[Char]’ Expected type: String Actual type: IO String
How can I solve this?
Start with reading some basic Haskell book/tutorial. That should tell you how to e.g. use 'do' notation, or `liftM`, to achieve what you want.
/M
-- Magnus Therning OpenPGP: 0xAB4DFBA4 email: magnus@therning.org jabber: magnus@therning.org twitter: magthe http://therning.org/magnus _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
-- Jonathan Skårstedt Bergsgårdsgärdet 39 Lgh 1108 424 32 Göteborg Mobil: 073 - 76 20 20 7
Dananji, Haskell explicitly separates "pure" from "impure", so "readFile <file>" returns not a string, but rather an action, which tells haskell to read a string. In order to "use" a result of some IO action as a pure value, you have several ways, most popula of which is a do-notation. main :: IO () main = do s <- readFile "somefile.txt" putStrLn (show (doSplit s)) In the code above, variable "s" is "pure", it has type String and you can use it as you want. Do-notation is essentially a sugar to callback mechanism, where in order to use a value of some IO-computation you write a function-callback that will be called with a pure value of computation result. This code is the same as previous one, but without do-notation: main :: IO () main = readFile "somefile.txt" >>= (\s -> putStrLn (show (doSplit s))) I highly recommend reading "Learn You A Haskell" book http://learnyouahaskell.com/ , which explained these concepts really well to me. On Mon, May 25, 2015 at 9:44 AM, Dananji Liyanage <dan9131@gmail.com> wrote:
Hi All,
I'm writing a code, where the input is read from a text file using: readValues = readFile "Input.txt"
Since the type of this is 'IO String', I can't use this in the consequent functions.
For an example: I want to split this as follows within another function
extractInput url method template | isURI url == True = getList values components | otherwise = [] where components = splitTemplate readValues values = getURL (splitURL url) method
This gives the following error:
Couldn't match type ‘IO String’ with ‘[Char]’ Expected type: String Actual type: IO String
How can I solve this?
Thanks in advance!
-- Regards, Dananji Liyanage
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Thank you for the nice explanation! I understood it for some extent, and will read further on I/O. On Mon, May 25, 2015 at 9:53 PM, Kostiantyn Rybnikov <k-bx@k-bx.com> wrote:
Dananji,
Haskell explicitly separates "pure" from "impure", so "readFile <file>" returns not a string, but rather an action, which tells haskell to read a string. In order to "use" a result of some IO action as a pure value, you have several ways, most popula of which is a do-notation.
main :: IO () main = do s <- readFile "somefile.txt" putStrLn (show (doSplit s))
In the code above, variable "s" is "pure", it has type String and you can use it as you want. Do-notation is essentially a sugar to callback mechanism, where in order to use a value of some IO-computation you write a function-callback that will be called with a pure value of computation result. This code is the same as previous one, but without do-notation:
main :: IO () main = readFile "somefile.txt" >>= (\s -> putStrLn (show (doSplit s)))
I highly recommend reading "Learn You A Haskell" book http://learnyouahaskell.com/ , which explained these concepts really well to me.
On Mon, May 25, 2015 at 9:44 AM, Dananji Liyanage <dan9131@gmail.com> wrote:
Hi All,
I'm writing a code, where the input is read from a text file using: readValues = readFile "Input.txt"
Since the type of this is 'IO String', I can't use this in the consequent functions.
For an example: I want to split this as follows within another function
extractInput url method template | isURI url == True = getList values components | otherwise = [] where components = splitTemplate readValues values = getURL (splitURL url) method
This gives the following error:
Couldn't match type ‘IO String’ with ‘[Char]’ Expected type: String Actual type: IO String
How can I solve this?
Thanks in advance!
-- Regards, Dananji Liyanage
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
-- Regards, Dananji Liyanage
participants (4)
-
Dananji Liyanage -
Jonathan Skårstedt -
Kostiantyn Rybnikov -
Magnus Therning