ppaul74
ppaul74

Reputation: 751

Ocaml function to convert a tuple into a list

I have an (int * string) tuple which I want to covert into a list. The tuple is of the form (N, E) where is N is the number of occurances of element E. The function should return a list with N occurences of E in it. Example is below. Lets assume this function is called tuple_decode.

tuple_decode (1, "A") -> ["A"]
tuple_decode (2,"B") -> ["B";"B"]
tuple_decode (4,"C") - > ["C";"C";"C";"C"]

The tuple_decode function is as follows

let tuple_decode acc (n,elem)   = 
let add_one_elem i = 
    match i  with
           0 -> acc
         | i -> elem :: acc ; add_one_elem (i-1)  (* Line 184 *)
in
add_one_elem n 
;;

when I try to compile this function I get the following error.

File "all_code.ml", line 184, characters 11-22:
Warning 10: this expression should have type unit.
File "all_code.ml", line 184, characters 25-37:
Error: Unbound value add_one_elem

Could someone help me figure out why I get this error and warning.

Regards Puneet

Upvotes: 2

Views: 5279

Answers (2)

David
David

Reputation: 71

As @pad has already answered your question sufficiently, a nice solution would also be:

let decode (n, elem) = List.init n (fun _ -> elem)

Upvotes: 0

pad
pad

Reputation: 41290

The warning comes from sequence composition using ;. When you write S1 ; S2, the compiler expects S1 to have unit type. But here S1 returns a list (elem::acc) whose value will be thrown away. Moreover, since you didn't pass acc as an argument, its value doesn't change after all recursive calls.

The error is due to recursive use of add_one_elem. Because you didn't use rec keyword, when add_one_elem (i-1) is called, OCaml doesn't know add_one_elem is being recursively defined.

Moreover, acc should be a parameter of add_one_elem to accumulate results:

let tuple_decode (n, elem) = 
  let rec add_one_elem i acc = 
      match i  with
      | 0 -> acc
      | i -> add_one_elem (i-1) (elem::acc)
  in add_one_elem n [] 

Upvotes: 6

Related Questions