All the examples that we have discussed so far are static in nature. In this chapter, we will learn to communicate dynamically with the users. We will learn different input and output techniques used in Haskell.
We have so far hard-coded all the inputs in the program itself. We have been taking inputs from static variables. Now, let us learn how to read and write from an external file.
Let us create a file and name it "abc.txt". Next, enter the following lines in this text file: "Welcome to Howcodex. Here, you will get the best resource to learn Haskell."
Next, we will write the following code which will display the contents of this file on the console. Here, we are using the function readFile() which reads a file until it finds an EOF character.
main = do let file = "abc.txt" contents <- readFile file putStrLn contents
The above piece of code will read the file "abc.txt" as a String until it encounters any End of File character. This piece of code will generate the following output.
Welcome to Howcodex Here, you will get the best resource to learn Haskell.
Observe that whatever it is printing on the terminal is written in that file.
Haskell also provides the facility to operate a file through the command prompt. Let us get back to our terminal and type "ghci". Then, type the following set of commands −
let file = "abc.txt" writeFile file "I am just experimenting here." readFile file
Here, we have created a text file called "abc.txt". Next, we have inserted a statement in the file using the command writeFile. Finally, we have used the command readFile to print the contents of the file on the console. Our code will produce the following output −
I am just experimenting here.
An exception can be considered as a bug in the code. It is a situation where the compiler does not get the expected output at runtime. Like any other good programming language, Haskell provides a way to implement exception handling.
If you are familiar with Java, then you might know the Try-Catch block where we usually throw an error and catch the same in the catch block. In Haskell, we also have the same function to catch runtime errors.
The function definition of try looks like "try :: Exception e => IO a -> IO (Either e a)". Take a look at the following example code. It shows how you can catch the "Divide by Zero" exception.
import Control.Exception main = do result <- try (evaluate (5 `div` 0)) :: IO (Either SomeException Int) case result of Left ex -> putStrLn $ "Caught exception: " ++ show ex Right val -> putStrLn $ "The answer was: " ++ show val
In the above example, we have used the inbuilt try function of the Control.Exception module, hence we are catching the exception beforehand. Above piece of code will yield below output in the screen.
Caught exception: divide by zero