我试图通过使用我的foldl函数来计算浮点列表中两个连续元素的所有平方和。
let rec foldl (f: 'b -> 'a -> 'b) (accum: 'b) (lst: 'a list) : 'b = match lst with
|[] -> accum
|x::xs -> foldl f (f accum x) xs
let sum_sqrt_sums (mylist: float list) : float = match mylist with
|[] -> raise(Failure "Nope")
|[x] -> raise(Failure "No!")
|x::xs -> foldl (fun x y -> sqrt (x +. y)) x xs
我跑
时有两个不同的结果sum_sqrt_sums [4.0; 2.0; 6.0; 3.0];;
- : float = 2.43039103901312092
sqrt(4.0 +. 2.0) +. sqrt(2.0 +. 6.0) +. sqrt(6.0 +. 3.0) ;;
- : float = 8.27791686752936862
我的和函数中的逻辑有什么问题?
答案 0 :(得分:4)
您的功能sum_sqrt_sums
无法计算
sqrt(4.0 +. 2.0) +. sqrt(2.0 +. 6.0) +. sqrt(6.0 +. 3.0)
但是
sqrt (sqrt (sqrt(2.0 +. 4.0) +. 6.0) +. 3.0)
你想要做的是保持在累加器中看到的最后一个元素将它添加到下一个元素并将它们的平方和加到累加器中:
let sum_sqrt_sums = function
| [] | [_] -> raise(Failure "Nope")
| x::xs ->
let _, res = foldl (fun (x, acc) y -> (y, sqrt (x +. y) +. acc)) (x, 0.) xs in
res
(作为旁注,您的 foldl
功能是 List.fold_left
功能)
更新(具有不同变量名称的版本以避免混淆):
let sum_sqrt_sums = function
| [] | [_] -> raise(Failure "Nope")
| x::xs ->
let _, res = foldl (fun (e, acc) y -> (y, sqrt (e +. y) +. acc)) (x, 0.) xs in
res
答案 1 :(得分:1)
to_tuple
:将列表转换为元组列表
let rec to_tuple aux l = match l with
| [] -> aux | [x] -> aux
| a::(b::tl as ll) -> to_tuple ((a,b)::aux) ll;;
to_tuple [] [4.0; 2.0; 6.0; 3.0];;
- : (float * float) list = [(6., 3.); (2., 6.); (4., 2.)]
最后一步:
List.fold_left (fun acc (x,y) -> acc+. sqrt (x+.y)) 0. [(6., 3.); (2., 6.); (4., 2.)];;