API Annotatons in a FunBind

Alan & Kim Zimmerman alan.zimm at gmail.com
Tue Dec 23 13:49:01 UTC 2014


I suspect it will be possible to move the fun_id and is_infix information
directly into the Match, since it seems to be used via a MatchWrapper for a
Match each time.

Should I attempt this, and if so should it be in D538? I am really keen to
get this into 7.10, so do not want to push big changes through it it means
missing the boat.


In terms of the variations of (  + ), the whole thing is parsed as a
RdrName, and carries API annotations.

For interest, I dug through Parser.y when making test cases for
ghc-exactprint and identified the following cases which all produce a
RdrName, and have corresponding API Annotations.

        |  'type' qcname            {% amms (mkTypeImpExp (sLL $1 $> (unLoc
$2)))
                                            [mj AnnType $1,mj AnnVal $2] }

        | '(' qconsym ')'       {% ams (sLL $1 $> (unLoc $2))
                                       [mo $1,mj AnnVal $2,mc $3] }

        | '(' consym ')'        {% ams (sLL $1 $> (unLoc $2))
                                       [mo $1,mj AnnVal $2,mc $3] }

        | '`' conid '`'         {% ams (sLL $1 $> (unLoc $2))
                                       [mj AnnBackquote $1,mj AnnVal $2
                                       ,mj AnnBackquote $3] }

        | '`' varid '`'         {% ams (sLL $1 $> (unLoc $2))
                                       [mj AnnBackquote $1,mj AnnVal $2
                                       ,mj AnnBackquote $3] }
        | '`' qvarid '`'        {% ams (sLL $1 $> (unLoc $2))
                                       [mj AnnBackquote $1,mj AnnVal $2
                                       ,mj AnnBackquote $3] }

        | '(' ')'                      {% ams (sLL $1 $> $ getRdrName
unitTyCon)
                                              [mo $1,mc $2] }
        | '(#' '#)'                    {% ams (sLL $1 $> $ getRdrName
unboxedUnitTyCon)
                                              [mo $1,mc $2] }


        | '(' commas ')'        {% ams (sLL $1 $> $ getRdrName (tupleTyCon
BoxedTuple
                                                        (snd $2 + 1)))
                                       (mo $1:mc $3:(mcommas (fst $2))) }
        | '(#' commas '#)'      {% ams (sLL $1 $> $ getRdrName (tupleTyCon
UnboxedTuple
                                                        (snd $2 + 1)))
                                       (mo $1:mc $3:(mcommas (fst $2))) }
        | '(' '->' ')'          {% ams (sLL $1 $> $ getRdrName funTyCon)
                                       [mo $1,mj AnnRarrow $2,mc $3] }
        | '[' ']'               {% ams (sLL $1 $> $ listTyCon_RDR) [mo
$1,mc $2] }
        | '[:' ':]'             {% ams (sLL $1 $> $ parrTyCon_RDR) [mo
$1,mc $2] }
        | '(' '~#' ')'          {% ams (sLL $1 $> $ getRdrName eqPrimTyCon)
                                        [mo $1,mj AnnTildehsh $2,mc $3] }

        | '(' qtyconsym ')'             {% ams (sLL $1 $> (unLoc $2))
                                               [mo $1,mj AnnVal $2,mc $3] }
        | '(' '~' ')'                   {% ams (sLL $1 $> $ eqTyCon_RDR)
                                               [mo $1,mj AnnTilde $2,mc $3]
}

tyvarop : '`' tyvarid '`'       {% ams (sLL $1 $> (unLoc $2))
                                       [mj AnnBackquote $1,mj AnnVal $2
                                       ,mj AnnBackquote $3] }

Alan

On Tue, Dec 23, 2014 at 3:25 PM, Simon Peyton Jones <simonpj at microsoft.com>
wrote:

>  Also, there is currently no location information for the fun_id for an
> infix definition, which can move around depending on the size of the left
> operand, and the choices made for whitespace.
>
>
>
> Good point.  So is the field only needed for an equation in infix form?
> Can we get rid of fun_infix, and replace with a mabe_infix field in the
> Match, used only for (a) FunBind that is (b) infix?
>
>
>
> In ordinary expressions I still don’t understand how you distinguish
>
>             map ( +) xs
>
> from
>
>             map (+ ) xs
>
>
>
> Simon
>
>
>
> *From:* Alan & Kim Zimmerman [mailto:alan.zimm at gmail.com]
> *Sent:* 23 December 2014 12:16
> *To:* Simon Peyton Jones
> *Cc:* ghc-devs at haskell.org
> *Subject:* Re: API Annotatons in a FunBind
>
>
>
>
>
> On Tue, Dec 23, 2014 at 1:59 PM, Simon Peyton Jones <simonpj at microsoft.com>
> wrote:
>
>  If you do this
>
> ·         Please make Match into a record (it ought to be already)
>
>  Ok
>
>  ·         Put a Note on the fun_id field, with an example like the one
> you give
>
>  Ok
>
>
>
> I’m not really sure if Haskell lets you mix infix and prefix notation for
> the same function definition, as you have done.  The Report is silent on
> this question. I’m inclined to think “no”.
>
>
>
>  Currently a FunBind has a fun_infix field saying whether the definition
> uses infix notation.  That is fine if “no” above.
>
>
>
> If all are prefix or infix, do you still need the new field in Match?
> Would it matter only for operators where you want to know where to put the
> parens?  Even in normal code, how are you distinguishing (+ ) from ( +) or
> whatever?
>
>
>
>
>
> The example I gave is an empirical test, it is currently accepted by GHC.
> The function as a whole is infix, it is just the alternate representation
> can be used for the individual Match definitions.
>
> There are straightforward rules as to whether a given fun_id needs parens
> or backquotes. The problem is that with source-to-source conversions the
> original must be reproduced exactly, and the code author has freedom to put
> arbitrary whitespace between the surrounding parens/backquotes and the
> actual identifier.  Hence the original fun_id is needed as an anchor for
> the API annotations.
>
> Also, there is currently no location information for the fun_id for an
> infix definition, which can move around depending on the size of the left
> operand, and the choices made for whitespace.
>
>
>
> In earlier versions of HaRe we were forced to scan through the rich token
> stream for a match to pick up this information.
>
> Alan
>
>
>
>
>
> Simon
>
>
>
> *From:* ghc-devs [mailto:ghc-devs-bounces at haskell.org] *On Behalf Of *Alan
> & Kim Zimmerman
> *Sent:* 15 December 2014 21:16
> *To:* ghc-devs at haskell.org
> *Subject:* API Annotatons in a FunBind
>
>
>
> After individual FunBinds have been parsed, they are combined in
> getMonoBind.
>
> In the process, all the original FunBind fun_id's bar one are discarded,
> including its location.
>
> This causes a problem for source-to-source conversions of functions such
> as the following
>
> (&&&  ) [] [] =  []
> xs    &&&   [] =  xs
> (  &&&  ) [] ys =  ys
>
> Where there are compound RdrNames, and each has different spacing.
>
> I am proposing to add a (Maybe (Located id)) to the Match datatype to deal
> with this.
>
>
> data Match id body
>   = Match
>
>         Maybe (Located id) -- fun_id in subsequent function equations
>
>         [LPat id]               -- The patterns
>         (Maybe (LHsType id))    -- A type signature for the result of the
> match
>                                 -- Nothing after typechecking
>         (GRHSs id body)
>
> Is this a problem?
>
> Alan
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/ghc-devs/attachments/20141223/f852f6be/attachment-0001.html>


More information about the ghc-devs mailing list