
On Sat, Feb 13, 2016, at 01:25, Ben Gamari wrote:
Christopher Allen
writes: Prelude> let myList = [1, 2, 3 :: Integer] Prelude> let myList' = myList ++ undefined Prelude> :t myList myList :: [Integer] Prelude> :t myList' myList' :: (?callStack::GHC.Stack.Types.CallStack) => [Integer]
...
This isn't just a pedagogical problem, this is a UX problem. The users don't _care_ that call stack information is being carried around. Why would they? It happens without any mention in the types in almost every other programming language.
Well, in the case of implicit call stacks users arguably *need* to care whether call stack information is carried around: you only get call stack information when you explicit request request one. This is one of the limitations of the implicit callstack mechanism.
That being said, the example that you offer is a bit suspicious to the point where I suspect it's a bug. As far as I know, the solver should not introduce new callstack constraints: if a CallStack constraint doesn't exist in the available context the solver should simply satisfy it with an empty callstack and that should be the end of it (Eric, correct me if I'm wrong).
Indeed, 7.10.2, which also had an early version of implicit callstack support, did exactly this. I haven't yet looked any further into what may have changed, but I have opened #11573 to track this.
The inferred CallStack is not a bug, it was added to fix #10845. The problem is that in a function like foo :: HasCallStack => ... foo x = let bar y = undefined in bar x we *need* to infer a CallStack for bar (due to the structure of the constraint solver) in order to link foo's CallStack to undefined. Currently, this extends to inferring CallStacks for top-level binders without explicit type signatures. Pedagogic concerns aside, I don't think this is a big deal as it's standard practice to provide explicit signatures. But it wouldn't be hard to make an exception for top-level binders. What *is* a bug is that GHC shows the implicit parameter in the inferred signature. We don't expose those anymore in the CallStack API, instead we use a type synonym HasCallStack. GHC should infer HasCallStack constraints instead. Eric