Search code examples
rascal

change properties of an element in a set and put it back in the set


Here's the problem,

Suppose we have a datatype, and a set of the datatype:

data Color=red(int n, str name)|black(int n, str name);

set[Color] coloredBalls={red(1,"a"), red(2,"b")};

I would like to iterate through the elements of the set and change the elements as follows:

for(Color aColor <- coloredBalls)
{
    if(aColor.n == 2)
        aColor.str="bb"

    //I would like to change the node: red(2,"b") to red(2,"bb") in the set coloredBalls
    //but am unable to express it in Rascal, unless I recourse to using a "Map", which I
    //think obfuscates the code quite a bit. Maybe using switch/visit with case does the trick?
}

Solution

  • There are many ways to build the new set you want to have (you can't actually change the existing set of course).

    You can use visit:

    coloredBalls = visit (coloredBalls) {
      case red(a,b) => red(a, b + "b")
    }
    

    Or use a comprehension with an is:

    coloredBalls = { x is red ? x[name=name+"b"] : x | x <- coloredBalls};
    

    Or with pattern match on the generator side:

    coloredBalls = {red(a, b + "b") | red(a,b) <- coloredBalls} + { y | y <- coloredBalls, !(y is red)};
    

    Or with a pattern match on the insert side of the comprehension:

    coloredBalls = {red(a,b) := c ? red(a,b+"b") : c | c <- coloredBalls};