monads are described as the haskell solution to deal with IO. I was wondering if there were other ways to deal with IO in pure functional language.
Imperative Functional Programming by Peyton Jones and Wadler is a must read if you are interested in functional IO. The other approaches that they discuss are:
type Dialogue = [Response] -> [Request]
main :: Dialogue
Continuations - each IO operation takes a continuation as argument
Linear types - the type system restricts you in a way that you cannot copy or destroy the outside state, which means that you can't call a function twice with the same state.