Ocaml表达式混淆

问题描述 投票:0回答:2

我写了这个ocaml函数:

(* int Base.List.t -> Base.Int.t x Base.Int.t *)
let min_and_max lst =
  let mmax = ref Float.neg_infinity
  and mmin = ref Float.infinity in
    List.iter ~f:(fun v -> let fv = Float.of_int v in 
                  if fv > !mmax then mmax := fv
                  else if fv < mmin then mmin := fv)
              lst;
    (Int.of_float !mmin, Int.of_float !mmax)

它应该返回整数列表的最小值和最大值,但是当我编译时,我收到此错误:

File "02-exercises/24-refs/problem.ml", line 25, characters 21-23:
Error: This expression has type Base.Float.t = float
       but an expression was expected of type int

该错误指向该函数中的第一个if语句。我必须犯一个非常明显的错误,但我看不到它。


Solution taking into account the answers and comments so far:

let min_and_max lst =
  match lst with
  | [] -> failwith "Cannot find min and max of empty list"
  | v::[] -> (v,v)
  | a::b::rest -> 
    let mmax = ref (max a b)
    and mmin = ref (min a b) in
      List.iter ~f:(fun v -> 
                      if v > !mmax then mmax := v;
                      if v < !mmin then mmin := v)
                rest;
      (!mmin, !mmax)
function tuples ocaml
2个回答
1
投票

我不明白你的编译器是如何抛出这个错误的。您的代码包含以前应检测的几个错误:

  1. 你错误地使用了标签。
  2. 在其他方面,你正在与ref mmin进行比较,而不是与其内容相比 - 你错过了!-。
  3. 你混淆int_of_float函数和Int.of_float,它不存在。

此外,该功能的逻辑原理还不够。例如,列表的第一个值将始终输入mmax变量,因为它将大于负无穷大。但如果这个数值最小呢?

除了上述之外,在这种情况下将整数转换为浮点数是没有意义的,并且导致精度损失和性能降低。也没有必要使用refs。

这不是在OCaml上下文中继续进行的规范方法。在OCaml中,尝试找到最简单的解决方案非常重要,因为一旦您开始使用类型复杂化,您最终无法解决灾难。

我建议你一个更简单的问题解决方案,许可证组成一个多态函数,而不仅仅是整数:

let min_and_max lst =
    (List.fold_left (fun a b -> if a < b then a else b) (List.hd lst) lst),
    (List.fold_left (fun a b -> if a > b then a else b) (List.hd lst) lst);;

这是一个优雅的选择,此外它基于终端递归。但是,在该方案中,您可以自己重新定义函数,而无需使用预定义的函数来遍历列表。您也可以选择一个回合中的两个数字,但这样做会更复杂一些。


2
投票

Base禁用多态比较:您需要使用本地open来比较浮点数与><Float.(fv > !mmax )

p.s。:对float的无偿转换(以及引用的使用)有点奇怪且不是最优的。

© www.soinside.com 2019 - 2024. All rights reserved.