To complete Sibi answer >> can be seen as the ; in other languages like C or C++..
When you do in C (or equivalent in other language)
printf("foo"); printf("bar");
You obviously print foobar (the side effect) but those calls to printf also have a return value, which in our case is the length being printed ie 3 3. Have you ever wonder what happen to those numbers ? They get ditched, because in C, expr 1; exp 2, means
- evaluate expr1
- ditch its result
- evaluate expr2
(At that point, you could ask yoursef why should the compiler bother evaluating expr1 if it's to discard its result ? Because of the side effect. In the case of printf the side effect is to print something. You are rarely interested in the returned value itself.)
So ; can be seen as an operator taking 2 expression and returning a new one. This is exactly the same as what the >> operator do.
When you write
print "foo" >> print "bar"
it's exactly equivalent to printf("foo");printf("bar") except (and that's a major difference) >> is not something magic like ; in C. >> it's a user defined operator and can be redefined for each type of Monad. This is why Haskell programmers love Monad so much : In short, it allows you to redefine your own the behavior of ;.
As we seen, in C ; just evaluate an expression and discard it's value. In fact, it's bit more complicated because it doesn't if it's a break or a return. The Nothing in the Maybe monad could be seen as a break or a return. >> evaluates the first expression, and stop if it's Nothing. Otherwise it discards it's value and carry on.
You first example can be seen in C (I think it's valid C)
3; return
and
return; 3
The first example, compute 3, discard its value and returns. The second, returns straight away.
To answer you question when is it usefull ? Pretty much all the time when you are using IO, even though you rarely see it.
Instead of writing
print "foo" >> print "bar"
Haskell provides a syntaxic sugar which transforms (pretty much) newlines to >> via the do-notation, so you'll write
do print "foo" print "bar"
which is strictly equivalent to the former version (It fact the do notation version is transformed to the previous one by the compiler).
It is even also equivalent to (even though rarely used)
do print "foo"; print "bar"
To summarize, >> can be seen as an equivalent to ; or newline is other languages with the difference that it's exact meaning depends on the context (which Monad is acting on). >> in a Maybe monad is different from >> in a IO Monad.