[Haskell-cafe] Getting both the value and name of a variable in one expression

Michael Sloan mgsloan at gmail.com
Wed Aug 21 16:31:08 UTC 2019


One potential solution here is to have checkGrammar_take2 return an
expression which returns an expression.  I haven't tried compiling
this, but something roughly like:

checkGrammar_2 name = [| if valueFine $(varE name) then varE name else
error "value isn't fine" |]

Then it'd be used like $($(checkGrammar_2 'thename)).  The th-orphans
package can also be useful for this because it provides Lift instances
for the TH AST.

-Michael

On Tue, Aug 20, 2019 at 10:36 AM Christopher Done <chrisdone at gmail.com> wrote:
>
> Hi all,
>
> Do we have already a syntax for ‘foo that also contains the typed value like TExp?
>
> I have e.g. an AST that I want to do more static checks on it that aren’t as convenient to do in the type system. Here’s an example:
>
> -- | Check the grammar spec to produce a grammar.
> checkGrammar :: (SchemaName, [(SchemaName, Schema)]) -> Q Exp
> checkGrammar (toplevel, rules) =
>   if M.size rulesMap /= length rules
>     then error "Duplicate rule names in grammar."
>     else lift (Grammar {grammarToplevel = toplevel, grammarRules = rulesMap})
>   where
>     rulesMap = M.fromList rules
>
> -- | Grammar for Haskell.
> grammar :: Grammar
> grammar = $(checkGrammar $ runDefine $ mdo
>   -- General expression
>   expression       <- rule "Expression" (ChoiceSchema [variable, constructor, parentheses
>                                                       ,tuple, let', application, string])
>   application      <- rule "Application" (CompositeSchema [expression, expression])
>   parentheses      <- rule "Parentheses" (CompositeSchema [openParenSchema, expression, closeParenSchema])
>
> ...
>  pure expression)
>
> Here I do a trivial check for duplicates. After I’ve checked the
> expression at compile-time, I Lift it so that it can be used at
> runtime. That’s pretty good. But some types like (a -> b) don’t Lift. So
> an alternative would be:
>
> grammar = $(checkGrammar_take2 thename 'thename)
>
> In which checkGrammar_take2 would:
>
> Use thename at compile-time for a check.
> If the check passes, then return (VarE thename)
>
> E.g.
>
> checkGrammar_take2 value name = if valueFine value then varE name else
> error "value isn't fine"
>
> That’s actually quite a good solution because it avoids a lift, and I
> didn’t transform the AST. It’s also more efficient than lifting.
>
> But there’s no checked relationship between thename and ‘thename.
> checkGrammar_take2 has no way of knowing that they refer to the same
> thing. See?
>
> Hence, if I could get e.g. `thename to produce both the value and a
> name for the value, that would be cool. My gist doesn’t go this
> far. It might look like this:
>
> checkGrammar_take2 namedValue = if valueFine (getValue namedValue) then getExp namedValue else error "value isn't fine"
>
> and call it like:
>
> mygrammar = checkGrammar_take2 `thename
>
> So the semantics would be roughly similar to
>
> [|| thename ||] :: TExp a
>
> but you’d get
>
> `thename :: Named a
>
> where
>
> data Named a = { namedThing :: a, nameOfThing :: Name }
>
> I feel like the more DSLs I design, the more I’d like something like this to perform my static checks.
>
> Cheers,
>
> Chris
>
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.


More information about the Haskell-Cafe mailing list