[GHC] #14131: Difference between newtype and newtype instance

GHC ghc-devs at haskell.org
Mon Aug 21 09:38:45 UTC 2017


#14131: Difference between newtype and newtype instance
-------------------------------------+-------------------------------------
        Reporter:  Iceland_jack      |                Owner:  (none)
            Type:  bug               |               Status:  patch
        Priority:  normal            |            Milestone:
       Component:  Compiler          |              Version:  8.2.1
      Resolution:                    |             Keywords:  TypeFamilies
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:  #7938, #9574,     |  Differential Rev(s):  Phab:D3872
  #13985                             |
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by simonpj):

 I'm not happy with Phab:D3872.  Currently we have
 {{{
 type HsTyPats pass = HsImplicitBndrs pass [LHsType pass]
 }}}
 That sugggests that the implicit binders scope only over the patterns.
 But as we know, they don't.  They scope over the RHS too.  And indeed, as
 this ticket discusses, we may have variables that are implicitly bound in
 the RHS, but are not even mentioned on the LHS.

 These `HsTyPats` are used in `DataFamInstDecl` and `TyFamInstEqn` (only).
 For the latter:
 Currently we have
 {{{
 type TyFamInstEqn  pass = TyFamEqn pass (HsTyPats pass)
 type TyFamDefltEqn pass = TyFamEqn pass (LHsQTyVars pass)

 data TyFamEqn pass pats
   = TyFamEqn
        { tfe_tycon  :: Located (IdP pass)
        , tfe_pats   :: pats
        , tfe_fixity :: LexicalFixity    -- ^ Fixity used in the
 declaration
        , tfe_rhs    :: LHsType pass }
 }}}
 where the implicit binders inside `tfe_pats` weirdly scopes over the
 `tfe_rhs`.  Instead we can have
 {{{
 type TyFamInstEqn  pass = HsImplicitBndrs (TyFamEqn pass [HsType pass])
 type TyFamDefltEqn pass = HsImplicitBndrs (TyFamEqn pass [LHsTyVarBndr
 pass])
 }}}
 I have not worked through the details, but it seems right to wrap the
 implicit binders around everything that they scopes over.  I suspect
 that'll make the code easier too.

 It's similar for `DataFamInstDecl`.  Currently we have:
 {{{
 data DataFamInstDecl pass
   = DataFamInstDecl
        { dfid_tycon     :: Located (IdP pass)
        , dfid_pats      :: HsTyPats   pass
        , dfid_fixity    :: LexicalFixity
        , dfid_defn      :: HsDataDefn pass
        , dfid_fvs       :: PostRn pass NameSet }
 }}}
 Instead we could have
 {{{
 type DataFamInstDecl pass                  -- Implicit bndrs here
   = HsImplicitBndrs pass (DataFamInstEqn pass)

 data DataFamInstEqn pass
   = DataFamInstEqn
        { dfid_tycon     :: Located (IdP pass)
        , dfid_pats      :: [LHsType pass]  -- No implicit bndrs
        , dfid_fixity    :: LexicalFixity
        , dfid_defn      :: HsDataDefn pass
        , dfid_fvs       :: PostRn pass NameSet }
 }}}
 Bubt that's still a bit strange, because the `dfid_fvs` should really be
 outside the `HsImplicitBndrs`.  (And it is for `TyFamEqn`.  So perhaps a
 better way would be to make `DataFamInstDecl` and `TyFamInstDecl` look a
 bit more like each other, thus
 {{{
 type DataFamInstDecl pass = FamInstDecl pass (HsDataDefn pass)
 type TyFamINstDecl   pass = FamInstDecl pass (LHsType    pass)

 data FamInstDecl pass rhs
   = FamInstDecl
        { fid_eqn  :: LFamInstEqn pass rhs
        , fid_fvs  :: PostRn pass NameSet }

 type LFamInstEqn pass rhs = Located (FamInstEqn pass rhs)

 type FamInstEqn pass rhs = HsImplicitBndrs (FamEqn pass [LHsType] rhs)

 data FamEqn pass pats rhs
   = TyFamEqn
        { tfe_tycon  :: Located (IdP pass)
        , tfe_pats   :: pats
        , tfe_fixity :: LexicalFixity
        , tfe_rhs    :: rhs }
 }}}

 We still need the typechecker test for comment:8.

 Finally: we need user-manual comments to explain what's accepted and what
 is rejected.

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


More information about the ghc-tickets mailing list