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 Traits
Oh, 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 Entity
would have a mix of types in it? Not just oneEntity
type 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: Jul 06 2025 at 12:14 UTC