
#14963: ghci -fdefer-type-errors can't run IO action from another module -------------------------------------+------------------------------------- Reporter: elaforge | Owner: (none) Type: bug | Status: new Priority: high | Milestone: 8.4.2 Component: GHCi | Version: 8.4.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by goldfire): After a long discussion of design possibilities, Simon and I came to the following: 1. The current design is broken, as described in this ticket. 2. If we want to handle all rebindable syntax in a general fashion, we were unable to come up with anything simpler than the "impenetrable" code that exists. And, indeed, to fix the current flaw would likely require adding `HList`s or some such, making it even worse. 3. Much of the current complication comes from the handling of `>>=`, which has an intricate type. Specifically, we need `(>>=) :: ty1 -> (ty2 -> ty3) -> ty4`. However, it would also be quite cool if something like `(>>=) :: ty1 -> (forall a. ty2 -> ty3) -> ty4` were allowed. This effectively means that a `<-` operator in a `do` could bind an existential variable without using a pattern-match. And, if the user wrote `(>>=)` literally (without `do`), then this would indeed be possible. So it would be nice. The complication specifically stems from the fact that the code processing `BindStmt`s needs to know `ty2` and `ty3`, so we must decompose the type of `(>>=)`'s second argument. In order to do this, we need to skolemize any `forall`d variables, and skolemization requires an implication constraint, causing the bug in this ticket. 4. Rebindable syntax that decomposes list constructors suffers a similar fate, but that's not nearly as painful as `(>>=)`. Though I'm still not fully convinced, we resolved to make the treatment of rebindable syntax simpler and less general. Specifically: a. Reduce `SyntaxOpType` to have two constructors: `SynAny :: SyntaxOpType` and `SynType :: ExpType -> SyntaxOpType`. b. Make new functions `tcBindOp`, `tcFromListOp`, and `tcFromListNOp` that handle the special cases for `(>>=)` and the list functions. These won't use general mechanisms, but just be a bit repetitive with `tcSyntaxOp`. c. The `SynRho` case of `tcSyntaxOp` will be dropped. Instead, clients of `tcSyntaxOp` that need rho-types will arrange to instantiate/skolemize the sigma-types that `tcSyntaxOp` provides as needed. This will duplicate code, but it means that `tcSyntaxOp` no longer needs to be written in CPS style. It will also allow this ticket to be resolved. d. This still won't handle cases like `fromListN :: (forall a. Int) -> [b] -> c`, where one parameter of a bit of rebindable syntax has a known type, but that known type might be redundantly quantified. Handling such a case would require CPSing again, and so we won't. This means that rebindable syntax will be a bit less expressive than the manual has heretofore promised. But the only lost cases are surely of the form above, where there is an unused quantified type variable. We can arrange for a suitable error message in these cases. This change will require a user manual update. e. When all this is done, the extra flexibility in the `SyntaxExpr` type -- with its argument wrappers and result wrapper -- won't be needed. Instead, `tcSyntaxOp` can return a plain old `HsExpr`, suitably wrapped. Accommodations will have to be made in `BindStmt` and the places where list operators might crop up to store extra `HsWrapper`s to be applied to arguments. f. A Note will be placed near `tcSyntaxOp` and the bind/list functions describing this design plan. If, in the future, we want more rebindable syntax, it might encourage us to re-adopt the more general -- but more complicated -- scheme currently in place. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14963#comment:11 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler