Why can\'t I do this:
import Data.Char
getBool = do
c <- getChar
if c == \'t\'
then IO True
else IO False
instead of using
There is very little magic around IO
and ST
monads, much less than most people believes.
The dreaded IO type is just a newtype
defined in GHC.Prim:
newtype IO a = IO (State# RealWorld -> (# State# RealWorld, a #))
First of all, as can be seen above the argument of IO
constructor is not the same as the argument of return
. You can get a better idea by looking at a naive implementation of State
monad:
newtype State s a = State (s -> (s, a))
Secondly, IO is an abstract type: it's an intentional decision not to export the constructor so you can neither construct IO
nor pattern match it. This allows Haskell to enforce referential transparency and other useful properties even in presence of input-output.