
#15493: Elide empty dictionaries -------------------------------------+------------------------------------- Reporter: mnoonan | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: 8.6.1 Component: Compiler | Version: 8.4.3 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: | -------------------------------------+------------------------------------- Description changed by mnoonan: Old description:
Suppose you define a type class `C` with no methods, and use it as a constraint on a function `f :: C => Foo`. GHC's generated Core for `f` currently passes an empty dictionary for `C`. With optimizations, it seems to be true that at use sites, calls to `f` will be replaced with calls to an inner function that skips the typeclass dictionary. But can I count on this optimization always working?
Would it possible to get a guarantee that the `C =>` constraint will have no run-time overhead, by dropping it entirely from the generated Core? Or is there a subtlety that prevents this from being sound?
For context, I would like to implicitly pass compile-time evidence that various properties hold (e.g. such-and-such a list is non-empty), while retaining a guarantee that the evidence will have no run-time cost. Like this:
{{{ newtype Named a name = Named a
class Fact p
-- Ideally, we'd have a guarantee that the following function -- compiles to exactly the same code as `Prelude.head` head :: Fact (IsCons xs) => (a `Named` xs) -> a head xs = Prelude.head (coerce xs) }}}
New description: Suppose you define a type class `C` with no methods, and use it as a constraint on a function `f :: C => Foo`. GHC's generated Core for `f` currently passes an empty dictionary for `C`. With optimizations, it seems to be true that at use sites, calls to `f` will be replaced with calls to an inner function that skips the typeclass dictionary. But can I count on this optimization always working? Would it possible to get a guarantee that the `C =>` constraint will have no run-time overhead, by dropping it entirely from the generated Core? Or is there a subtlety that prevents this from being sound? For context, I would like to implicitly pass compile-time evidence that various properties hold (e.g. such-and-such a list is non-empty), while retaining a guarantee that the evidence will have no run-time cost. Like this: {{{ newtype Named a name = Named a class Fact p -- Ideally, we'd have a guarantee that the following function -- compiles to exactly the same code as `Prelude.head` head :: Fact (IsCons xs) => ([a] `Named` xs) -> a head xs = Prelude.head (coerce xs) }}} -- -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15493#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler