Сумма квадратов сумм OCaml - PullRequest
0 голосов
/ 02 мая 2018

Я пытаюсь сложить все квадратные суммы двух последовательных элементов из списка с плавающей запятой, используя мою функцию 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

Что не так с моей логикой в ​​моей функции сумм?

Ответы [ 2 ]

0 голосов
/ 02 мая 2018

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.)];;
0 голосов
/ 02 мая 2018

Ваша функция 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...