Question: After seeing how the List and Maybe monads are defined, I naturally became curious about how
 the operations `>>=` and `return` are defined for the IO monad.

Answer: 
There is no specific implementation for `IO`; it's an abstract type, with the exact implementation left undefined by the Haskell Report. Indeed, there's nothing stopping an implementation implementing `IO` and its `Monad` instance as compiler primitives, with no Haskell implementation at all.

Basically, `Monad` is used as an *interface* to `IO`, which cannot itself be implemented in pure Haskell. That's probably all you need to know at this stage, and diving into implementation details is likely to just confuse, rather than give insight.

That said, if you look at GHC's source code, you'll find that it represents `IO a` as a function looking like `State# RealWorld -> (# State# RealWorld, a #)` (using an [unboxed tuple](http://www.haskell.org/ghc/docs/latest/html/users_guide/primitives.html) as the return type), but this is misleading; it's an implementation detail, and these `State# RealWorld` values do not actually exist at runtime. `IO` is *not* a state monad,1 in theory or in practice.

Instead, GHC uses *impure* primitives to implement these IO operations; the `State# RealWorld` "values" are only to stop the compiler reordering statements by introducing data dependencies from one statement to the next.

But if you really want to see GHC's implementation of `return` and `(>>=)`, here they are:

```
returnIO :: a -> IO a
returnIO x = IO $ \ s -> (# s, x #)

bindIO :: IO a -> (a -> IO b) -> IO b
bindIO (IO m) k = IO $ \ s -> case m s of (# new_s, a #) -> unIO (k a) new_s

```

where `unIO` simply unwraps the function from inside the `IO` constructor.

It's important to note that `IO a` represents a *description* of an impure computation that could be run to produce a value of type `a`. The fact that there's a way to get values out of GHC's internal representation of `IO` doesn't mean that this holds in general, or that you can do such a thing for all monads. It's purely an implementation detail on the part of GHC.

1 The [state monad](http://learnyouahaskell.com/for-a-few-monads-more#state) is a monad used for accessing and mutating a state across a series of computations; it's represented as `s -> (a, s)` (where `s` is the type of state), which looks very similar to the type GHC uses for `IO`, thus the confusion.
They don't do anything special, and are just there for sequencing actions. It would help if you think of them with different names:

>>= becomes "and then, using the result of the previous action,"

>> becomes "and then,"

return becomes "do nothing, but the result of doing nothing is"

This turns this function:

```
main :: IO ()
main = putStr "hello"
   >>  return " world"
   >>= putStrLn

```

becomes:

```
main :: IO ()
main = putStr "hello" and then,
       do nothing, but the result of doing nothing is " world"
       and then, using the result of the previous action, putStrLn

```

In the end, there's nothing magical about IO. It's exactly as magical as a semicolon is in C.