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

Christopher Done chrisdone at gmail.com
Tue Aug 20 16:36:23 UTC 2019


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 ExpcheckGrammar (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 :: Grammargrammar = $(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:

   1. Use thename at compile-time for a check.
   2. If the check passes, then return (VarE thename)

E.g.

checkGrammar_take2 value name = if valueFine value then varE name
elseerror "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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20190820/01b205a7/attachment.html>


More information about the Haskell-Cafe mailing list