New type of expressions containing (error ...) includes noisy implicit parameter
Eric Seidel
eric at seidel.io
Sat Feb 13 16:54:01 UTC 2016
On Sat, Feb 13, 2016, at 01:25, Ben Gamari wrote:
> Christopher Allen <cma at bitemyapp.com> 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
More information about the ghc-devs
mailing list