
foo = do (1 :: Int)
While intuitively this should be disallowed, it seems a pity that desugaring couldn't be totally separated from typechecking. Hmm.
or perhaps not. while a type-free desugaring, followed by type-checking, seems more modular, i'd rather see any type errors in terms of the sugared syntax. which kind of rules out total separation, doesn't it? 'do {e}' --> 'e' could be interpreted in a type-free sense, but 'do {e1;e2}' --> 'e1 >> e2' already exposes the type constraints. i prefer to think of it as a kind of eta-expansion: i don't know the type of 'e', but i do know something about the type of '\x->e x' and i would like to know something about the type of 'do {e}'. monad laws have the same issue, btw: 'return () >> e' --> 'e' only makes sense for monadic 'e' claus