How is IO monad actually implemented?in sense of, what would be the actual implementation of the main function?
How would I call haskell function (IO) f
The IO monad is basically implemented as a state transformer (similar to State), with a special token RealWorld. Each IO operation depends on this token and passes it when it finishes. unsafeInterleaveIO introduces a second token, so that a new IO operation can start, while the other one is still doing its work.
Usually, you don't have to care about the implementation. If you want to call IO-functions from other languages, GHC cares about removing the IO wrapper. Consider this small snippet:
printInt :: Int -> IO ()
printInt int = do putStr "The argument is: "
print int
foreign export ccall printInt :: Int -> IO ()
This generates a symbol to call printInt from C. The function becomes:
extern void printInt(HsInt a1);
Where HsInt is just a (depending on your platform) typedefd int. So you see, the monad IO has been removed completely.