Haskell - guardian of functional purity but violator of software engineering purity?
Yesterday, after 1 year of studying Haskell, I tried to write my first program involving I/O. I decided to convert a Perl program that I had written which provides lookup of state names via their 2-letter code and vice-versa. A day later, I had something written, but was worried because all of my functions were using
fmap to pull things out of the IO monad. In other words, my entire library reeked of I/O.
The next day, Cale Gibbard wrote a very nice version of my program which relegated the IO to a single function.
But the thing is, you still have to use my module from the main program with the awareness that the data is coming from an IO source. Now, a basic principle of software engineering is to separate the interface from the implementation. There is no way to use the Haskell implementation of my module without full knowledge that said module is returning me data that is coming from I/O... outside of using something called
unsafeIO which I know nothing about.
why does this matter?
Let's say I have a function which does something to a list of functions of type (String -> String) but one of the functions has to open a file to get its string:
sfnProc :: [(String -> String)] -> [Int]
sfnProc = map (\f -> length f)
so the problem becomes that the one function that returns a string via I/O cannot be used opaquely: the referential transparency of Haskell is killing need for opaque API of software engineering.