I wrote a bunch of code in Haskell to create an index of a text. The top function looks like this:
index :: String -> [(String, [Integer])] index a = [...]
Now I want to give this function a String read from a file:
index readFile "input.txt"
Which won't work because readFile is of type FilePath -> IO String.
Couldn't match expected type 'String' against inferred type 'IO String'
I see the error, but I can't find any function with type:
IO String -> String
I guess the key to success lies somewhere under some Monads, but I could not find a way to solve my problem.
Haskell separates pure functions from computations where side effects must be considered by encoding those side effects as values of a particular type. Specifically, a value of type (IO a) is an action, which if executed would produce a value of type a .
IO is the way how Haskell differentiates between code that is referentially transparent and code that is not. IO a is the type of an IO action that returns an a . You can think of an IO action as a piece of code with some effect on the real world that waits to get executed.
An IO String is a String in the IO-Monad. If a function in the IO-Monad returns an IO String, you get the String by doing: do str <- ioFunc. A function is in the IO-Monad when it needs IO-access and has to return IO types.
The String type is the most basic form of representing strings in Haskell. It is a simple type synonym for a list of unicode characters (the Char type).
You can easily enough write a function that calls the readFile action, and passes the result to your index function.
readAndIndex fileName = do text <- readFile fileName return $ index text
However, the IO monad taints everything that uses it, so this function has the type:
readAndIndex :: FilePath -> IO [(String, [Integer])]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With