[Haskell-beginners] Using IO values for computations

Jonathan Skårstedt jonathan.skarstedt at gmail.com
Mon May 25 15:49:52 UTC 2015


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 at therning.org>:

> On 25 May 2015 at 08:44, Dananji Liyanage <dan9131 at 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 at therning.org   jabber: magnus at therning.org
> twitter: magthe               http://therning.org/magnus
> _______________________________________________
> Beginners mailing list
> Beginners at 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/beginners/attachments/20150525/7c2ed8d1/attachment.html>


More information about the Beginners mailing list