hi
Working with type annotations is extremally frustrating I have spend two hours straight and I can't make working even simple thing, what to do here :
nodeType : { children : List (Num a), locked : Bool, value : List *} where a implements Hash & Eq
g : List * -> nodeType
g = \ lst ->
{ children : [], locked : Bool.true, value : [] }
This topic was moved here from #beginners > working with type annotation by Artur Swiderski.
why it does not compile how to fix it ?
why it is so unintuitive and difficult ?
I can see a few issues with your example, its quite complex because it combines a lot of different features, and even includes some really advanced stuff like Abilities.
You're not asking me to help you with a working version, but you would like to know how to fix it.
I find it helpful to start with a really simple type annotation. Then run roc check to confirm it compiles like I expect. Then incrementally change it and re-run roc check. This way I get immediate feedback when I do something incorrectly and I know exactly where the issue is. In this way the compiler is a really helpful teacher for the type system. Also adding unit tests is another great way to check understanding of types.
one problem is that nodeType : is syntactically invalid because it's not capitalized. (I'm on mobile so not sure what the error message is, but I'm guessing it's not clear about this!)
It needs to be NodeType : rather than nodeType :
I notice some other problems:
a, are always type variables), that variable must be listed next to the alias name. So since NodeType contains an a (specifically in Num a), it needs to be NodeType a :*, you have to choose names for those type variables (such as a instead of *, although in this particular type, a is already being used for something else, so we'd probably want to replace the * with b). So it can't be value : List *, it has to be value: List b (and then NodeType a b : because b needs to be listed next to the alias name just like a did.)where a implements Hash & Eq applies to the a in Num a. I'm guessing that's not necessary and can be removed!These sound like good issues to track around improving our error massages to help make this experience nicer
it works thx for tips @Richard Feldman , but this syntax is difficult nevertheless . Thankfully this is optional, if I have to keep track of those types during prototyping stage, it would be just to much. I hope it stays this way as -> optional feature
The FAQ says
"A valuable aspect of Roc's type system is that it has decidable principal type inference. This means that:
At compile time, Roc can correctly infer the types for every expression in a program, even if you don't annotate any of the types."
so I don't think that feature is going away. I think it's fairly fundamental to the design decisions behind the language.
Last updated: Nov 09 2025 at 12:14 UTC