F# 延续出现 StackOverflowException
大家好,我正在实现一个 F# 函数,它采用两个类型的列表:(int*float) 列表。这两个列表的长度不同。 这对的int元素是一个递增的代码。 我想做的是创建一个新列表,其中包含两个具有相同代码的列表中每两个元素的 (int*float) 。需要注意的是,列表中的代码是按递增顺序排列的。 这些列表可能有点长,比如 2-3000 个元素,所以我尝试使用连续传递风格来实现这个函数,以避免 StackOverflowExceptions。但遗憾的是我失败了。
这是这个功能,希望大家指点!
let identifiedDifference list1 list2 =
let rec produceResult (l1, l2) k =
match l1,l2 with
| [],[]
| _,[]
| [],_ -> k []
| (code,rate:float)::xs, (code2,rate2)::ys ->
if code = code2
then
produceResult (xs, ys) (fun c -> (code,Math.Abs(rate-rate2))::(k c))
elif code > code2
then produceResult (l1, ys) k
else produceResult (xs, l2) k
produceResult (list1, list2) id
我做错了什么吗?
Hi guys I'm implementing an F# function that takes two lists of type : (int*float) list. These two lists have different lentgths.
The int element of the couple is an increasing code.
What I wanted to do is create a new list that will contain a couple (int*float) for each two elements of the two lists that have the same code. It's important to note that codes in lists are in increasing order.
These lists are probably a little long, like 2-3000 elements., so I tried to implement this function using continuation passing style in order to avoid StackOverflowExceptions. but sadly i failed.
This is the function, i hope you will give me any hints!
let identifiedDifference list1 list2 =
let rec produceResult (l1, l2) k =
match l1,l2 with
| [],[]
| _,[]
| [],_ -> k []
| (code,rate:float)::xs, (code2,rate2)::ys ->
if code = code2
then
produceResult (xs, ys) (fun c -> (code,Math.Abs(rate-rate2))::(k c))
elif code > code2
then produceResult (l1, ys) k
else produceResult (xs, l2) k
produceResult (list1, list2) id
I've done something wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
应该是
使其尾递归:
这也将修复以相反顺序返回的结果。
should be
to make it tail-recursive:
This will also fix your results being returned in reverse order.
问题出在这一行
这里你调用延续,但这个调用不是尾部,因为你仍然需要 cons (code,Math.Abs(rate-rate2)) 到 (kc) 的结果
我想你可以从以下构建结果列表由内而外并反转最终结果:
编辑:
经过第二次查看后,我认为这里不需要 CPS,使用累加器应该可以解决问题:
The problem lies in this line
Here you invoke continuation but this call is not tail because you still need to cons (code,Math.Abs(rate-rate2)) to the result of (k c)
I guess you can build result list from the inside out and just reverse final result:
EDIT:
after second look I think CPS is not needed here and using accumulator should do the trick:
对于替代答案,请看一下: http://fssnip.net/75
该函数需要几个序列并返回根据某些匹配函数匹配的对。我还没有对其进行过体积测试。
该函数实际上在较大的代码片段中使用: http://fssnip.net/76
For an alternative answer, take a look at this: http://fssnip.net/75
The function takes a couple of sequences and returns pairs which match according to some matching function. I haven't volume-tested it.
The function is actually used in the larger snippet here: http://fssnip.net/76