
My bad, I restate: a value cannot be both static and dynamic. Or an object and a morphism. Or an element and a function. Sure, you can treat a morphism as an object, but only by moving to a higher (or different) level of abstraction. That doesn't erase the difference between object and morphism. If you do erase that difference you end up with mush. getChar /looks/ like an object, but semantically it must be a morphism. But it can't be a function, since it is non-deterministic. So actually the logical contradiction comes from the nature of the beast.
Another reason it's confusing to newcomers: it's typed as "IO Char", which looks like a type constructor. One would expect getChar to yield a value of type IO Char, no? But it delivers a Char instead. This is way confusing. So I take "type IO foo" to mean "type foo, after a side effect". In a sense "getChar :: IO Char" isn't even a true type signature.
It does yield a value of type IO Char, which it also happens that you can ask the Haskell runtime to interpret by combining it with other IO values using >>= and invoking it from the top-level. *When interpreted in this way* it delivers a Char, but that's precisely the point at which we move to the different level of abstraction you mention above. Ganesh ============================================================================== Please access the attached hyperlink for an important electronic communications disclaimer: http://www.credit-suisse.com/legal/en/disclaimer_email_ib.html ==============================================================================