Сравнение возвращаемого значения опции со значением опции - PullRequest
0 голосов
/ 17 октября 2018

Я пытаюсь сделать что-то супер простое ...

let Average (a : float list) : (float option) =
    let add (x : float) (y : float) = x+y

    match a.Length with
    | 0 -> None
    | 1 -> None
    | _ -> Some((List.fold add 0.0 a)/(float)a.Length)    

let CompareResult func input expected =
         (func input) = expected

Это две мои функции.Когда я делаю CompareResult Average [5,8; 6,6; 9,4; 3,5; 4,0] (около 5,86), я получаю ложь.

Любые идеи, почему это может быть, очень приветствуются.Спасибо

1 Ответ

0 голосов
/ 18 октября 2018

Помимо расхождений, возникающих из-за ограничений внутреннего представления, проблема также может быть вызвана потерей точности при вычислении среднего значения в арифметике с плавающей запятой.

5.86.ToString "G17"
// val it : string = "5,8600000000000003"
(Seq.average [5.8;6.6;9.4;3.5;4.0]).ToString "G17"
// val it : string = "5,8599999999999994"

Рассмотрите возможность использования более подходящих числовых данныхвведите:

Seq.average [5.8;6.6;9.4;3.5;4.0] = 5.86
// false
Seq.average [5.8M;6.6M;9.4M;3.5M;4.0M] = 5.86M
// true

Чтобы ответить на реальный вопрос, как проверить равенство Option<float> значений: «подняв» поплавки из опций, а затем выполнив проверку на равенство.Лифт - это обычная операция для монад в функциональном программировании.

Чрезвычайно упрощенно, мы собираемся запускать тест на заказ только тогда, когда оба аргумента являются Some -случаями.Это легко сделать путем сопоставления с образцом в случаях различного объединения.

let eps = 1e-7  // or whatever is sensible in your domain
let equalityCompareFloatOption x y =
    match x, y with
    | Some x', Some y' -> abs(x' - y') < eps
    | _ -> x = y
// val equalityCompareFloatOption : x:float option -> y:float option -> bool

equalityCompareFloatOption
     (Seq.average[5.8;6.6;9.4;3.5;4.0] |> Some) (Some 5.86)
// val it : bool = true
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...