OCaml:为什么这段代码会产生类型检查错误?

时间:2009-09-09 01:07:22

标签: ocaml typechecking

这是我的代码:

let avg l =
    List.fold_left ( +. ) 0. l /. float (List.length l);;
let variability l =
    let xbar = avg l in 
    let odp = (List.map (fun i -> ((float) i -. xbar) ** 2.0) l) in
    let sum = List.fold_left ( +. ) 0. odp in
    sum /. (float) length l;;

将此输入到顶层会产生以下结果:

val avg : float list -> float = <fun>
#         Characters 107-108:
      let odp = (List.map (fun i -> ((float) i -. xbar) ** 2.0) l) in
                                                                ^
Error: This expression has type float list but is here used with type
         int list

我一直在尝试使用它很长一段时间,但我无法弄清楚为什么会产生错误。是否认为l是一个int列表?

解决方案:(来自下方。谢谢!)

let avg l =
    List.fold_left ( +. ) 0. l /. float (List.length l);;
let variability l =
    let xbar = avg l in 
    let odp = (List.map (fun i -> (i -. xbar) ** 2.0) l) in
    let sum = List.fold_left ( +. ) 0. odp in
    sum /. (float) (List.length l);;

1 个答案:

答案 0 :(得分:2)

let xbar = avg l会将l推断为类型float list,这似乎是您想要的。但是,在表达式List.map (fun i -> ((float) i -. xbar) ** 2.0) l中,您在映射函数中使用(float) ifloat的类型为int -> float,因此i被推断为类型int。这会导致l被推断为类型int list,无法与float list统一,从而导致类型检查错误。

我相信最后一行也是错误的。它应该使用List.length,而不仅仅是length,而且我认为围绕float的参数需要括号,而不是float本身。

此代码应该有效:

let avg l =
    List.fold_left ( +. ) 0. l /. float (List.length l);;
let variability l =
    let xbar = avg l in 
    let odp = (List.map (fun i -> (i -. xbar) ** 2.0) l) in
    let sum = List.fold_left ( +. ) 0. odp in
    sum /. float (List.length l);;