F #: Writing a function that recursively builds a list of tuples and modifies a mutable variable

This question is related to this previous thread .

I followed Thomas's suggestion using this code and everything works fine:

let GetSameColorNeighs (grid:Option<Ball>[,], row, col, color:Color) = let rec loop (row, col) = seq { if not (row < 0 || col < 0 || row > MaxLineNumber - 1 || col > BallsPerLine - 1) then let ball = grid.[row,col] match ball with | Some(ball) -> if (!ball.visited = false || not <| ball.color.Equals(color)) then // Not sure what you want here - yield items using 'yield'? // [row , col] else ball.visited := true yield row, col // Add single item to results yield! loop(row + 1, col + 1) // Add all generated to results yield! loop(row - 1, col - 1) // -- || -- | None -> () } loop(row, col) |> Seq.toList 

The above code iterates over the 2d array of "balls" and returns a list of indices of adjacent balls of the same color.

Now I need to change the function so that it also returns a boolean value indicating whether at least one ball in the list satisfies a certain condition. I changed the code this way, but it seems that I cannot assign a mutable value inside this code:

 let GetSameColorNeighs (grid:Option<Ball>[,], row, col, color:Color) : List<int * int> * bool = let mutable b : bool = false let rec loop (row, col) = seq { if not (row < 0 || col < 0 || row > MaxLineNumber - 1 || col > BallsPerLine - 1) then let ball = grid.[row,col] match ball with | Some(ball) -> if (ball.visited = true || not <| ball.color.Equals(color)) then () else //HERE THE PROBLEM if (ball_satisfy_a_certain_condition) then b <- true ball.visited := true yield row, col // Add single item to results yield! loop(row + 1, col + 1) // Add all generated to results yield! loop(row - 1, col - 1) // -- || -- | None -> () } loop(row, col) |> Seq.toList, b 

It seems that a mutable variable cannot be obtained by closure (I don't know what that means).

I have 2 questions:

  • Why is the indicated assignment of a mutable variable incorrect?
  • How do I reorganize my code to achieve this?
+4
source share
1 answer

In short, you should use ref variables instead of mutable variables.

While mutable variables are allocated on the stack, ref variables are heap based. Each time you call the loop function, mutable values ​​are erased when ref values ​​still exist. Therefore, only ref values ​​are allowed to return to GetSameColorNeighs .

This question has been asked many times here. See Mutable. The variable β€œI” is used in an incorrect way.? and this blog for a more detailed discussion.

+4
source

Source: https://habr.com/ru/post/1385896/


All Articles