F#:编写递归构建元组列表的函数,语法错误
我正在尝试编写一个返回 List < 的递归函数。 int * int>,但我在语法上遇到了一些问题。
当递归结束时,该函数应该返回一个空列表,否则一个元组 (int * int) 与递归调用自身返回的列表合并:
let rec foobar () : List<int * int> =
if (recursionIsEnded) then
[]
else
foobar () :: (10, 10) // this is wrong
// (10,10) works, but I need to concatenate it with the elements returned by foobar recursive call
有人可以向我解释我做错了什么吗?
编辑:
我会尝试提供更多细节。 实际上我的功能有点复杂。我正在迭代一个二维数组,并使用满足特定条件的数组索引元素构建一个元组列表。实际上这是我的代码:
let rec GetSameColorNeighs(grid : Option<Ball> [,], row : int , col : int, color : Microsoft.Xna.Framework.Color) : List<int * int> =
if (row < 0 || col < 0 || row > MaxLineNumber - 1 || col > BallsPerLine - 1) then
[]
else
let ball = grid.[row,col]
match ball with
|Some(ball) ->
if (!ball.visited = false || not <| ball.color.Equals(color)) then
[row , col]
else
ball.visited := true
(row,col) ::GetSameColorNeighs(grid, row + 1, col + 1, color) :: GetSameColorNeighs(grid, row - 1, col - 1, color)
|None -> []
所以这里还有两个问题:):
如何修改以下行以使其编译?
(row,col) ::GetSameColorNeighs(grid, row + 1, col + 1, color) :: GetSameColorNeighs(grid, row - 1, col - 1, color)
有没有更好的方法可以做到这一点?
我不关心列表的元素顺序。
I'm trying to write a recursive function that return a List < int * int>, but I'm having some trouble with the syntax.
The function should return an empty list when the recursione ends, otherwise a tuple (int * int) merged with a List returned by a recursive call to itself:
let rec foobar () : List<int * int> =
if (recursionIsEnded) then
[]
else
foobar () :: (10, 10) // this is wrong
// (10,10) works, but I need to concatenate it with the elements returned by foobar recursive call
Could someone explain to me what I'm doing wrong?
EDIT:
I'll try to give more details .
Actually my function is a bit more complicated. I'm iterating through a 2d array and build a list of tuples with the array index elements that satisfy a certain condition. Actually that's my code:
let rec GetSameColorNeighs(grid : Option<Ball> [,], row : int , col : int, color : Microsoft.Xna.Framework.Color) : List<int * int> =
if (row < 0 || col < 0 || row > MaxLineNumber - 1 || col > BallsPerLine - 1) then
[]
else
let ball = grid.[row,col]
match ball with
|Some(ball) ->
if (!ball.visited = false || not <| ball.color.Equals(color)) then
[row , col]
else
ball.visited := true
(row,col) ::GetSameColorNeighs(grid, row + 1, col + 1, color) :: GetSameColorNeighs(grid, row - 1, col - 1, color)
|None -> []
So here's 2 more question :):
How modify the following row in order to make it compile?
(row,col) ::GetSameColorNeighs(grid, row + 1, col + 1, color) :: GetSameColorNeighs(grid, row - 1, col - 1, color)
Is there any better way to do that?
I don't care about the list's elements order.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
Daniel 的解决方案对我来说看起来不错,但您不需要使用可变状态 (
ResizeArray
)。相反,您可以将loop
函数编写为序列表达式,使用yield
生成结果,并使用yield!
进行递归调用:Daniel's solution looks good to me, but you don't need to use mutable state (
ResizeArray
). Instead, you can write theloop
function as a sequence expression that generates results usingyield
and makes recursive calls usingyield!
:使用带有累加器的内部函数可能是最简单的方法(作为奖励,它是尾递归的)。
根据您的更新,我更喜欢可变的解决方案。像这样的东西
Using an inner function with an accumulator is probably the easiest way to do it (as a bonus it's tail recursive).
Based on your update, I'd prefer a mutable solution. Something like
由于 foobar 返回一个列表,您必须附加列表或连接,然后反转
(foobar())@(10,10)
但是我通常会以相反的方式执行此操作
,然后在以下情况下反转你回来了。上面的尾递归有一个问题,所以到了 tweek,你最终会得到类似的结果:
与将列表附加到列表相比,最终反转通常会导致更少的操作
Since foobar returns a list you either have to append the lists or concat and then reverse
(foobar())@(10,10)
however I'd usually doit the other way around
and then reverse when you return. the above have a problem with tail recursion so to tweek that you end up with something like:
reversing in the end should usually result in fewer operations than if you append a list to a list
虽然它是一个更简单的函数,但我希望它有助于说明这一点,因为您通过两个列表递归来构建元组。此函数采用 ([],[]) 形式的两个列表作为输入,并将每个元素作为新列表中的元组配对在一起。
给定两个长度相同的列表(如果它们长度不同,您将收到错误),每次递归都会将前两个元素配对为一个元组(x,y)。语法:
实际上只是说“用我们当前的元素(x,y)构建一个元组,然后继续用我们的列表的其余部分(xs,ys)构建元组。
运行:
您将得到输出:
Although it's a simpler function, I hope it helps illustrate the point as your recurse through two lists to build tuples. This function takes two lists as input in the form ([],[]), and pairs each element together as a tuple in a new list.
Given two lists of the same length (If they aren't the same length you'll get an error), each recursion will pair the first two elements into a tuple as (x,y). The syntax:
Is really just saying "Build a tuple with our current elements (x,y), then proceed building tuples with the rest of our lists (xs,ys).
Run:
And you'll get the output: