I have been trying to wrap my head around functional programming for a while now? I have looked up lambda calculus, LISP, OCML, F# and even combinatorial logic but the main
The way Haskell does it is by using monads see wikipedia and the explanation by Haskell on their page.
Basically the idea is that you do not get rid of the IO monad. My understanding is that you are able to chain functions that unwrap an IO monad and execute that function. But you are not able to remove the IO monad altogether.
Another example using monads that is not directly tied to IO is the Maybe Monad. This monad is 'unwrappable' in contrary to the IO monad. But it is easier to explain the use of monads using the Maybe monad. Let's assume you have the following function.
wrap :: Maybe x -> (x -> y) -> Maybe y
wrap Nothing f = Nothing
wrap (Just x) f = Just (f x)
now you can call wrap (Just 4) (5+)
which will return Just 9
.
The idea of the IO-monad is that you can use functions like (+5) on the internal type. The monad will assure that the functions will be called in serial, because every function is chained with the wrapping IO-monad.