views:

118

answers:

1

Here is my code:

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;;

Entering this into the toplevel produces the following:

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

I've been trying to work with this for a long time but I can't figure out why this is producting an error. Is it thinking that l is an int list?

SOLUTION: (from below. Thanks!)

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);;
+2  A: 

let xbar = avg l causes l to be inferred as type float list, which appears to be what you want. However, in the expression List.map (fun i -> ((float) i -. xbar) ** 2.0) l, you use (float) i in the mapping function. The type of float is int -> float, so i is inferred as type int. This causes l to be inferred as type int list, which fails to unify with float list, resulting in a type check error.

I believe the last line is also incorrect. It should use List.length, not just length, and I think you need parentheses around the argument to float, not float itself.

This code should work:

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);;
bcat