F# 递归总结由点列表给出的路径
F# Recursion to Summarize a Path given by List of Points
我是 F#
的新手,偶然发现了一个我感兴趣的问题。我正在尝试使用递归重新创建与 List.reduce
类似的功能。该函数使用 sumTwoPoints
计算坐标列表中两个元素和 returns 一个元素的总和。
let sumTwoPoints(x1, y1) (x2, y2) : float * float = (x1 + x2, y1 + y2)
到目前为止我做了什么:
let rec pathSum list =
match list with
| [] -> failwith "Empty List"
| head::next::rest -> sumTwoPoints head next :: rest
我的思考过程是这样的
// e0() e1() e2() e3() e4()...
// sumTwoPoints (e0 e1) = r1
// sumTwoPoints (r1 e2) = r2
// sumTwoPoints (r2 e3) = r3
// sumTwoPoints (r3 e4) = r4
// pathSum = r4
e0
表示列表中的元素。如果我们按照这个系统,head = e0
和 tail = e1
以及 rest
列表有剩余元素。我不确定是否要将新的 r1
添加到 rest
列表中,但这是我想到的。下一步,如果我的逻辑是正确的,就是将这个新列表传递给 pathSum
,但是再次获取,我不知道如何在代码中实现。
我提出的解决方案可能完全错误,如有任何建议或帮助,我们将不胜感激。
您需要修改函数以添加当前点的参数。
逻辑是它将列表的 'head' 添加到该点,然后使用该添加的结果和列表的其余部分递归调用自身。当最终用一个空列表调用它时,它只是 returns 点值。
let rec pathSum (current:float * float) list =
match list with
| [] -> current
| head::rest ->
let next = sumTwoPoints head current
pathSum next rest
初始调用必须传递初始值 (0, 0)
:
pathSum (0, 0) list
跟进 Charles Mager 的回答,您需要查看列表。它可以为空 []
或具有另一个列表的值 x::y
。如果你仔细看看你的功能
sumTwoPoints : (float * float) -> (float * float) -> (float * float)
pathSum : (float * float) list -> (float * float)
这样你就有了 rest
作为 (float * float) list
的类型,当用 pathSum
调用时,它给出了 (float * float)
的类型。这样您就可以使用函数 sumTwoPoints
而无需 next
let rec pathSum list =
match list with
| [] -> (0.0, 0.0)
| head::rest ->
sumTwoPoints head (pathSum(rest))
最后,您需要将 failwith
更改为零,否则递归将失败。
我是 F#
的新手,偶然发现了一个我感兴趣的问题。我正在尝试使用递归重新创建与 List.reduce
类似的功能。该函数使用 sumTwoPoints
计算坐标列表中两个元素和 returns 一个元素的总和。
let sumTwoPoints(x1, y1) (x2, y2) : float * float = (x1 + x2, y1 + y2)
到目前为止我做了什么:
let rec pathSum list =
match list with
| [] -> failwith "Empty List"
| head::next::rest -> sumTwoPoints head next :: rest
我的思考过程是这样的
// e0() e1() e2() e3() e4()...
// sumTwoPoints (e0 e1) = r1
// sumTwoPoints (r1 e2) = r2
// sumTwoPoints (r2 e3) = r3
// sumTwoPoints (r3 e4) = r4
// pathSum = r4
e0
表示列表中的元素。如果我们按照这个系统,head = e0
和 tail = e1
以及 rest
列表有剩余元素。我不确定是否要将新的 r1
添加到 rest
列表中,但这是我想到的。下一步,如果我的逻辑是正确的,就是将这个新列表传递给 pathSum
,但是再次获取,我不知道如何在代码中实现。
我提出的解决方案可能完全错误,如有任何建议或帮助,我们将不胜感激。
您需要修改函数以添加当前点的参数。
逻辑是它将列表的 'head' 添加到该点,然后使用该添加的结果和列表的其余部分递归调用自身。当最终用一个空列表调用它时,它只是 returns 点值。
let rec pathSum (current:float * float) list =
match list with
| [] -> current
| head::rest ->
let next = sumTwoPoints head current
pathSum next rest
初始调用必须传递初始值 (0, 0)
:
pathSum (0, 0) list
跟进 Charles Mager 的回答,您需要查看列表。它可以为空 []
或具有另一个列表的值 x::y
。如果你仔细看看你的功能
sumTwoPoints : (float * float) -> (float * float) -> (float * float)
pathSum : (float * float) list -> (float * float)
这样你就有了 rest
作为 (float * float) list
的类型,当用 pathSum
调用时,它给出了 (float * float)
的类型。这样您就可以使用函数 sumTwoPoints
而无需 next
let rec pathSum list =
match list with
| [] -> (0.0, 0.0)
| head::rest ->
sumTwoPoints head (pathSum(rest))
最后,您需要将 failwith
更改为零,否则递归将失败。