My guess is that you are running it in GHCi, which means that
it gets coerced to the IO monad.
"Coercion" doesn't quite capture it. Also it happens that the haskell research literature uses it in a technically specific context that doesn't apply here.
What's going on in
return (Just 3)
being _executed_ in ghci to produce
Just 3
is the REPL's defaulting to IO kicking in.
p.s. In the above, I've made distinct execution from evaluation. This helps folks navigate the beginner-hazardous terrain of overloaded English.