I'm just getting started with Roc and trying to get used to its tags and types, etc. Reading the tutorial it sounds great, but when I try to implement my data model I find I'm not sure how best to do it. I'm trying to implement the Concept types from this file. I created a tag union like this:
Role : { id : Str }
Concept : [
AtomicConcept { id : Str },
Conjunction { left : Concept, right : Concept },
ExistentialRestriction { role : Role, concept : Concept }
]
But sometimes I need to have List containing just one of those types, (like List Conjunction). In Scala all of these are also first class types. What's the recommended approach for this in Roc? I tried to make a type for the structure, like this:
ConjunctionRecord : {
left: Concept,
right: Concept
}
Concept : [
AtomicConcept { id : Str },
Conjunction ConjunctionRecord,
ExistentialRestriction { role : Role, concept : Concept }
]
But roc check gives an error: fatal runtime error: stack overflow
could you file an issue with repro on the stack overflow?
Oh, I think what you want to do is currently bugged in roc such that you can't clean write it in roc.
Fundamentally, your second example should work, but we have a recursive type issue currently.
It makes it so that the ConjunctionRecord need to be inlined into the Concept definition because it recursively uses Concept
What you can do currently:
# Define the limited type to avoid the bug
Concept : [
AtomicConcept { id : Str },
Conjunction { left : Concept, right : Concept },
ExistentialRestriction { role : Role, concept : Concept }
]
# When you need to use just the `ConjunctionRecord`, don't type, or type manually
usesConjunctionsOnly : List {left: Concept, right: Concept}
usesConjunctionsOnly = \list -> ...
Thanks! Would you say that my second approach would be the recommended style if not for the bug?
I think so.
In Scala I also define a trait Entity which groups things that have an id property. So AtomicConcept and Role are both entities. I would create a function like this:
signature : Concept -> Set Entity
I guess for that I would define another tag union, but I feel like I would repeat some of the info I've put in my Concept definition.
four options:
\{id} -> id it will extract from any record with an id field.Abilities which are very much like TraitsOh, though you want to put them all in a Set. I assume a Set Entity would have a mix of types in it? Not just one Entity type at a time?
Brendan Hansknecht said:
Oh, though you want to put them all in a
Set. I assume aSet Entitywould have a mix of types in it? Not just oneEntitytype at a time?
That's right.
If so, the tag approach is the only option. The tag is what enables unifying them in memory representation to put into a Set.
Great, thanks for all the info. I'll keep experimenting and hopefully get used to Roc's approach.
This looks like it could be the same stack overflow error: https://github.com/roc-lang/roc/issues/4709
Yeah, I think it is the same
A similar? issue that I haven't found a workaround for: https://github.com/roc-lang/roc/issues/5162
@Brendan Hansknecht I'm still trying to get my project to build—I opened a couple more issues on GitHub. Should I keep posting those as I encounter them? Don't want to become annoying. :-)
Generally better to post multiple bugs if you aren't sure they are duplicates and let us merge them.
Last updated: Nov 09 2025 at 12:14 UTC