Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert data from IO(String) to String in haskell [duplicate]

Possible Duplicate:
A Haskell function of type: IO String-> String

i'm reading some data from a file using the readFile function available in Haskell. But this function returns me some data stored as IO String. Does anybody knows how do I convert this data into a String type (or any function that reads String from a file, without the IO () type)?

like image 564
user1050519 Avatar asked Nov 16 '11 21:11

user1050519


2 Answers

It is a very general question about extracting data from monadic values.

The general idea is to use >>= function:

main = readFile foo >>= \s -> print s

>>= takes 2 arguments. It extracts the value from its first argument and passes it to its second argument. The first argument is monadic value, in this case of type IO String, and the second argument is a function that accepts a plain, non-monadic value, in this case String.

There is a special syntax for this pattern:

main = do
   s <- readFile foo
   print s

But the meaning is the same as above. The do notation is more convenient for beginners and for certain complicated cases, but explicit application of >>= can lead to a shorter code. For example, this code can be written as just

main = readFile foo >>= print

Also there are a big family of library functions to convert between monadic and non-monadic values. The most important of them are return, fmap, liftM2 and >=>.

The concept of monad is very useful beyond representing IO in a referentially transparent way: these helpers are very useful for error handling, dealing with implicit state and other applications of monads.

The second most important monad is Maybe.

like image 95
nponeccop Avatar answered Nov 15 '22 07:11

nponeccop


I'd treat the IO type as a functor in this case, and instead of getting the value out of it, I'd send my function inside it and let the Functor instance deal with creating a new IO container with the result from my function.

> :m +Data.Functor
> length <$> readFile "file.txt"
525

<$> is an alias for fmap. I like <$> more, but it's just a personal preference.

like image 32
Ionuț G. Stan Avatar answered Nov 15 '22 07:11

Ionuț G. Stan