这个问题与之前的帖子有关

我按照Tomas的建议使用这个代码,一切正常:

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

上面的代码遍历“球”的数组2d并返回具有相同颜色的相邻球的索引列表。

现在我必须修改函数,它返回一个布尔值,指示列表中至少有一个球是否满足某个条件。 我以这种方式更改了代码,但似乎我无法在该代码中分配一个可变值:

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's 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

似乎闭包不能获取可变变量(我不知道它意味着什么)。

所以我有两个问题:

  1. 为什么上面赋值给一个可变变量错了?
  2. 我应该如何重构我的代码以实现这一目标?

===============>>#1 票数:4 已采纳

简而言之,您必须使用ref变量而不是可变变量。

虽然可变变量在堆栈上分配,但ref变量是基于堆的。 每次调用loop函数后,当ref值仍然存在时,可变值将被清除。 因此,只有ref值才能在GetSameColorNeighs返回。

这个问题在这里被多次询问过。 请参阅可变变量'i'以无效方式使用。? 这篇博客文章进行了更深入的讨论。

  ask by Heisenbug translate from so

未解决问题?本站智能推荐:

2回复

C ++ - 类似F#函数中的静态变量

F#中有些模拟? 就像是 ?
1回复

为什么Fsharp Interactive允许闭包捕获可变变量?

使用Chris Smith的Programming F#3.0中的一个例子: 这按预期失败: 错误FS0407:可变变量'x'以无效方式使用。 闭包不能捕获可变变量。 现在将函数体剪切并粘贴到FSharp Interactive中: 它的工作原理!
2回复

F#中的尾递归:Quicksort的反转

嗨,我在理解尾递归方面有些困难。 我知道,避免无限循环以及内存使用非常重要。 我已经在“ Expert in F#”中看到了一些简单函数的示例,例如Fibonacci,但我认为当结果不同于数字时,我没有看到代码。 那么,累加器将是什么? 我不确定... 这是我编写的一个递归函数
2回复

递归地将列表解压缩为元素

我有一个列表,并希望单独返回每个元素。 基本上就像从堆栈中弹出一样。 例如: 但是,我实际上想要一个接一个地返回每个整数,直到列表为空,而不是迭代。 所以基本上是这样的: 不幸的是,我尝试使用折叠或扫描的递归解决方案甚至更好的尝试都没有成功。 例如,这只返回列表(与map
1回复

F#明确定义的可变变量错误它不是可变变量

我的代码中有几个可变变量。 除了一个以外,所有这些都可以工作! 变量d会出现一些错误,例如 问题是,当您查看我的代码时,该变量显然已定义为可变变量。 我认为这是必要的,因为我唯一想到的应该引起问题的是,它是变量定义之后的东西,使它再次变得不可变。
2回复

F#需要重写代码以不需要可变变量

我已经完成了我一直在从事的项目,但是我想返回并清理我的代码。 在这种情况下,我使用了一个可变变量,但是我希望我的代码不包含可变变量。 我将如何重写此代码段以返回布尔值,但又不可变? 任何帮助将不胜感激,加油!
1回复

如何将标签链接到F#中的可变变量?

我想在F#中创建一个标签,该标签使用可变变量返回值。 不幸的是,F#将此标签设置为恒定值。 如果可变值改变,则标签的值保持不变。 是不是有点矛盾? 有没有办法使标签(“ a”)依赖于可变变量(“ x”)?
3回复

可变变量的JS闭包

请帮助我找出循环期间本地“j”变量继续变化的原因: 我在类似的问题上阅读了很好的答案,但这不符合我的情况。 可以通过闭包访问可变变量。 我怎样才能解决这个问题?
1回复

如何在F#中使用可变列表?

我是F#的新手,我正在编写一个程序,要求找到某个列表的给定长度的每个子列表。 我不确定该怎么做,所以我读了这个问题 ,决定将答案移植到F#中。 这是我所拥有的: 编译器对以下几件事感到不高兴:它说没有List<int> , List<List<int>&
3回复

F#可变为不可变

Gday All, 我一直在涉及一些F#,我想出了一些我从一些C#代码中移植的字符串构建器。 它将对象转换为字符串,前提是它传递了属性中定义的正则表达式。 它可能对手头的任务有些过分,但出于学习目的。 目前,BuildString成员使用可变字符串变量updatedTemplat