- Various babel extensions
I tried to model the “core” with an open variant
-- x is additions to Expression
-- s is additions to Statement
-- p is additions to Pattern
newtype Statement (x :: # Type) (s :: # Type) (p :: # Type)
= Statement (Variant
( "ExpressionStatement" :: ExpressionStatement x s p
, "BlockStatement" :: BlockStatement x s p
, "EmptyStatement" :: Node ()
, "DebuggerStatement" :: Node ()
, "WithStatement" :: WithStatement x s p
, "ReturnStatement" :: ReturnStatement x s p
, "LabeledStatement" :: LabeledStatement x s p
, "BreakStatement" :: BreakStatement
, "ContinueStatement" :: ContinueStatement
, "IfStatement" :: IfStatement x s p
, "ThrowStatement" :: ThrowStatement x s p
, "WhileStatement" :: WhileStatement x s p
, "DoWhileStatement" :: DoWhileStatement x s p
, "ForStatement" :: ForStatement x s p
, "FunctionDeclaration" :: FunctionDeclaration x s p
, "VariableDeclaration" :: VariableDeclaration x s p
but then I literally don’t know how to populate those variables with anything other than
Is this a bad approach? Is this a solved problem?
Any help is appreciated.
I’m not sure if it is helpful in your context but I’ve extracted pieces of JS AST implementation from
purescript-in-purescript few months ago. I’ve not published this lib but it won’t be a problem to do this:
Thanks, I don’t think this is doing precisely what I want but it’s entirely possible that “what I want” is wrong so this is something to read
You should be able to do something like
Statement ("MyNewExpressionType" :: ...) ..., but the problem you will run into is these extended fields can’t be recursive, which probably is not what you want. Structural types in PureScript do not support recursion at the language level. One possibility is to factor the recursion out and use recursions schemes, however this will only work with a single point of recursion, whereas you need mutual recursion. See Exploring mutually recursive Variants. I have not taken this further, unfortunately.
The alternative to variants is to just create an extension point in your sum
data Statement f x s p
= ExpressionStatement ...
| BlockStatement ...
| CustomStatement (f x s p)
data MyCustomStatement x s p
= FancyJsStatement ...
type MyStatement = Statement MyCustomStatement
Thanks a lot man. This is great reading material. It’s weirdly satisfying to know why what I was attempting is impossible (or at least too difficult).
I think I’m going to give up on making it extensible and model the biggest superset of JS I want to work with.
I attempted something similar with ESTree a while back.
You might find this issue interesting. https://github.com/paulyoung/purescript-estree/issues/3