Hi,
I managed to express constraints of CSS selectors in types, so if CSS class applied to a tag that doesn’t have a proper context formed by ancestors and/or siblings of the tag, then a compilation error is produced.
E.g. for rule
.a > .b { }
and the DOM snippet where prerequisites for class b is not satisfied:
div_ </ div_ .= b
<div>
<div class="b">
</div>
</div>
Error: parent tag doesn’t have a class.
[([B, C "a"], [], [])]
Another case for siblings
.a + .b { }
div_ </ div_ </ div_ .= b
[([B], [], [[ [B], [C "a"]]])]
As far as I understand, Scala has support for GADTs and can generate/execute code at compilation. So I am curious about the feasibility of replicating such library in Scala.
Tag type has just 9 parameters responsible for tracking CSS and DOM interplay
data E
model
action
(en :: Symbol)
(es :: ElementStructure)
(re :: Maybe Root)
(ei :: Maybe Symbol)
(atrs :: [Symbol])
(knownIds :: KnownIDS)
(cls :: [Symbol])
(l :: [[[Seg]]])
(children :: [[SubSeg]])
2 Likes
That sounds really cool, and I would gladly help you, however I don’t understand anything ^^’
In particular:
So did you manage to do it in Scala’s type system, or a different language ?
And if in Scala, then which library are you talking about ?
The library is written in Haskell (GHC 9.12).
Before investing a lot of time in the project, I tried to find out if anyone had created such library before and besides Haskell, I check Scala and Rust. I have experience with Java, but Scala is mostly a mystery for me. At first glance the language has all prerequisites to achieve the goal (GADTs and TemplateHaskell equivalent), but devil is in details…
I see now, Scala probably has what you need given its type system is really powerful (+ typed macros + givens)
Given the above however, the “most Scala” implementation might look different from the haskel implementation.
And as you might guess, there is a lot to learn !
I hope this doesn’t disuade you tho, the language is very fun and powerful
1 Like
Yeah, the original post’s a bit hard to parse. But looking at that type signature — tracking both ancestor context and sibling relationships plus all the CSS data simultaneously — that’s the real lift in any language. Even with GADTs you’re juggling a lot of interdependent constraints.