[GHC] #10056: Inconsistent precedence of ~

GHC ghc-devs at haskell.org
Mon Feb 2 01:54:29 UTC 2015


#10056: Inconsistent precedence of ~
-------------------------------------+-------------------------------------
        Reporter:  crockeea          |                   Owner:
            Type:  bug               |                  Status:  new
        Priority:  normal            |               Milestone:
       Component:  Compiler          |                 Version:  7.8.4
  (Parser)                           |                Keywords:
      Resolution:                    |            Architecture:
Operating System:  Unknown/Multiple  |  Unknown/Multiple
 Type of failure:  GHC rejects       |               Test Case:
  valid program                      |                Blocking:
      Blocked By:                    |  Differential Revisions:
 Related Tickets:                    |
-------------------------------------+-------------------------------------

Comment (by goldfire):

 Here's what I know about all of this, to the best of my knowledge:

 - Types do ''not'' "inherit" fixity from terms. The type family `(+) :: *
 -> * -> *` (or whatever kinds) is completely and totally unrelated to the
 term-level variable `(+) :: Num a => a -> a -> a`.

 - There is no way in a fixity declaration to specify what namespace you
 want the declaration to operate over. So, in (what I consider to be) a
 terrible hack, a fixity declaration will affect either or both of local
 term-level and type-level definitions. So, if you have

 {{{
 (//) :: a -> a -> a
 (//) = ...
 type family (//) a b
 infixl 5 //
 }}}

   then ''both'' the term `(//)` and the type `(//)` get the given fixity.
 This isn't a case of one inheriting the fixity from the other or being at
 all related -- it's just a peculiar meaning given to a fixity declaration.

 - While the parser doesn't know what type a term has, it ''does'' know
 whether you're writing a term, a type, or a kind. So it can behave
 differently in each of these cases -- they're all syntactically distinct
 in Haskell source.

 - Traditional fixity declarations don't affect the parser. And, upon some
 thought, we realize they can't: a fixity declaration can't be acted upon
 until after (or in) the renamer, when we know where a symbol is declared.

 - `(~)` is parsed separately from the normal infix operators. Recall that
 `TypeOperators` used to require type-level operators to begin with `:`.
 `(~)` does not, and so it must be special. Now that `TypeOperators` has
 been changed, there actually doesn't seem to be a good reason to keep
 `(~)` special. It's declared (in `ghc-prim:GHC.Types`). It has magic in
 the solver, but there needs to be no magic dealing with naming or parsing.
 However, simply removing the magic causes several minor conundrums:
   - Do we require `TypeOperators` when `~` appears in source code?
 Currently, we don't.
   - Do we require `TypeFamilies` or `GADTs` when `~` appears in source
 code? Currently, we do, but if we drop the magic, this decision is
 suspect, especially if `~` isn't ever really acted on in the module
 (because it appears only on the RHS of a type synonym, say).
   - Should `(~)` be imported as part of the Prelude? If no, then a lot of
 code breaks. If yes, that implies that hiding the Prelude also hides
 `(~)`, breaking less code, but still breaking code.

   These issues are surmountable, perhaps, but when I looked at making `~`
 non-magical, I discovered both that it's technically quite straightforward
 and socially rather annoying for little benefit. I suppose there's a
 middle road where it's non-magical in the parser but magical in the
 renamer.

   When I realized how tangled this all was, I gave up, as I was just doing
 some cleaning. Now that bugs are actually appearing, there might be more
 incentive to come up with a consistent response.

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10056#comment:4>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list