Unit 4. IO in Haskell

 

So far in this book, you’ve seen many examples of the powerful things you can do with Haskell. A recurring theme of Haskell is that much of this power comes from simple things such as referential transparency and Haskell’s type system. But there has been one glaring omission so far: I/O.

No matter what your program does, no matter what language it’s written in, I/O is a hugely important part of software. It’s the point where your code meets the real world. So why haven’t you seen much Haskell involving I/O yet? The problem is that using I/O inherently requires you to change the world. Take, for example, getting user input from the command line. Each time you have a program that requests user input, you expect the result to be different. But in unit 1 we spent a great deal of time talking about how important it is that all functions take an argument, return a value, and always return the same value for the same argument. Another issue with I/O is that you’re always changing the world, which means you’re dealing with state. If you read a file and write to another, your programs would be useless if you didn’t change the world somewhere along the way. But again, avoiding state is one of the key virtues of Haskell discussed in unit 1.