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: Jul 06 2025 at 12:14 UTC