Why this code does not work and how to implement equivalent
modifyActive = \ head ->
updatedLst =
if List.isEmpty head.children == Bool.true then
[head]
else
head.children
updatedLst
a = { children : []}
kk =modifyActive a
tree like are rather quite basic structures how to accomplish creating them in Roc
I think I can workaround this problem using Tags a = { children : Childern []} <-- something like that
modifyActive = \ head ->
updatedLst =
when head.children is
Ok children ->
if List.isEmpty head.children == Bool.true then
[head]
else
head.children
Err -> []
updatedLst
This would definitely be something good to add to the examples.
I think with tags you'll still encounter self-referential issues later on.
You could go with something like this:
NodeID : U64
Node : { value: Str, children : List NodeID}
tree : Dict NodeID Node
tree = Dict.empty {}
|> Dict.insert 0 { value: "hey", children: [1]}
|> Dict.insert 1 { value: "hey!", children: []}
This particular code assumes you want to store a Str in each Node.
If you don't want to store anything in the Node, you could go with this:
NodeID : U64
Children : List NodeID
tree : Dict NodeID Children
tree = Dict.empty {}
|> Dict.insert 0 [1]
|> Dict.insert 1 []
thx I just encounter problems apparently what I am trying is impossible, but your solution will work for sure
btw, this crashes compiler
modifyActivetest = \ head ->
updatedLst =
when head.children is
Children children->
if List.isEmpty children == Bool.true then
[{ locked : Bool.false, children : Children [], value : [] }]
else
when List.last children is
Ok elem ->
if elem.locked == Bool.true then
[{ locked : Bool.false, children : Children [], value : [] }]
else
[modifyActivetest elem]
Err _ -> []
_ -> []
{ locked : head.locked, children : Children updatedLst , value : head.value }
www = { locked : Bool.false, children : Children [], value : [] }
uuu = modifyActivetest www
I think we have a few bugs to file here and track.
Brendan Hansknecht said:
I think we have a few bugs to file here and track.
- Recursion though lists/dicts/etc instead of tags should just work.
- We already have a super old bug for this, but the recursive tag definition issue if they aren't in a single definition.
- The crash is probably a separate issue and should be filed as well.
It turned out that through tags I was not able to accomplish anything as well, it fall apart when I tried do something useful in real life
In terms of language adaptation, as new user intuitively I would rather expect that language (any language) will figure out that what I am trying to do is perfectly fine. But still, if feature is missing (for technical or other reasons) I can live with this Dict approach presented by Anton
Yeah, I am not sure about the technical problems here, but I think it should just work. Gonna chat with others.
@Artur Swiderski This should work and be a lot nicer than dictionaries:
Node : [Branch (List Node)]
modifyActive : Node -> List Node
modifyActive = \head ->
Branch children = head
if List.isEmpty children then
[head]
else
children
the problem is that my code is sightly bit more complex then example I provided
my target function is
modifyActive : Node -> Node
not
modifyActive : Node -> List Node (this worked in some variations in other it crashed but not self reference problem)
the type I used was: Node : [ { branch : Branch (List Node), ... } ]
I have to check if this works with
Node : [ Element { branch : List Node, ... } ] ?? (I will check my code with this type used)
So to repeat :
Earlier
I fall into problems when I tried (this is equivalent code):
With type like this :
Node : [ { branch : Branch (List Node), ... } ]
I tried something like this :
modifyActive : Node -> Node
modifyActive = \head ->
Branch children = head
updatedList =
if List.isEmpty children then
[ ----> create new node element but no problem here <---]
else
when List.last children is
Ok child ->
# before I checked if child is eligible for modification but here it is irrelevant
List.dropLast children
|> List.append ( modifyActive child ) <--------in this line it failed with reference to itself problem
....
{ head & branch : updatedList } <-- function has this as return value
I think we are just giving you a misleading type error here. This code checks for me and should be similar to your goal above:
modifyActive : Node -> Node
modifyActive = \head ->
Branch children = head
when List.last children is
Ok child ->
List.dropLast children 1
|> List.append (modifyActive child)
|> Branch # This converts back from (List Node) to a Node
Err _ ->
# This is the list empty case, make new node or etc.
head
But I explicitly recover object in line
{ head & branch : Branch updatedList } <--- that was last line of my function
I will check tomorrow but keep in mind that I need different type. then you are using
something like:
Node : [ { branch : (List Node), ... } ] <--- this checked already and it failed on reference to itself
Node : [ { branch : Branch (List Node), ... } ] <--- this checked already and it failed on reference to itself
Node : [ Element { branch : (List Node), ... } ] <--- maybe this will work
Node : [Element { branch : Branch (List Node), ... } ] <--- or this
I need Node to be record (and maybe record usage is the problem ??)
I will try two last options in case of problems , Dict approach will work for sure
I am using like 2 weeks old Roc so maybe that's the problem I will update environment
I would expect Node: [Element { branch: List Node, ...}]
to work with current roc.
Also, I'll try to fix the base roc issue.
this may be the same problem as I mentioned before but this piece of code compiles but crashes
modifyActive = \ op, currentStructHead ->
Node head = currentStructHead
updatedLst =
if List.isEmpty head.children == Bool.true then
op head.children
else
when List.last head.children is
Ok node ->
Node child = node
if child.locked == Bool.true then
op head.children
else
modifyLastInList head.children (modifyActive op node )
Err _ -> []
Node {head & children : updatedLst }
main =
www = Node { locked : Bool.false, children : [], value : [] }
fun1 = (\ lst -> List.append lst (Node { locked : Bool.false, children : [], value : [] } ))
wataC = modifyActive fun1 www
.
.
.
I would rather consider it valid, or at least it would be nice to get some meaningful message out of execution if it is not
I placed it here https://github.com/roc-lang/roc/issues/5970
Last updated: Jul 06 2025 at 12:14 UTC