tags:

views:

71

answers:

2
+3  Q: 

Ocaml introduction

Hello Guys,

i'm trying to learn ocaml right now and wanted to start with a little program, generating all bit-combinations: ["0","0","0"] ["0","0","1"] ["0","1","0"] ... and so on

My idea is the following code:

let rec bitstr length list =
  if length = 0 then
    list
  else begin
    bitstr (length-1)("0"::list);
    bitstr (length-1)("1"::list);
  end;;

But i get the following error:

Warning S: this expression should have type unit.
val bitstr : int -> string list -> string list = <fun>
# bitstr 3 [];;
- : string list = ["1"; "1"; "1"]

I did not understand what to change, can you help me?

Best regards Philipp

+8  A: 

begin foo; bar end executes foo and throws the result away, then it executes bar. Since this makes only sense if foo has side-effects and no meaningful return value ocaml emits a warning if foo has a return value other than unit, since everything else is likely to be a programmer error (i.e. the programmer does not actually intend for the result to be discarded) - as is the case here.

In this case it really does make no sense, to calculate the list with "0" and then throw it away. Presumably you want to concatenate the two lists instead. You can do this using the @ operator:

let rec bitstr length list =
  if length = 0 then
    [list]
  else
    bitstr (length-1)("0"::list) @ bitstr (length-1)("1"::list);;

Note that I also mad the length = 0 case return [list] instead of just list so the result is a list of lists instead of a flat list.

sepp2k
ahh i see, thank you for the explanation! you really helped me!
Philipp Andre
+3  A: 

Although sepp2k's answer is spot on, I would like to add the following alternative (which doesn't match the signature you proposed, but actually does what you want) :

let rec bitstr = function
   0 -> [[]]
 | n -> let f e = List.map (fun x -> e :: x) and l = bitstr (n-1) in 
        (f "0" l)@(f "1" l);;

The first difference is that you do not need to pass an empty list to call the function bitsr 2 returns [["0"; "0"]; ["0"; "1"]; ["1"; "0"]; ["1"; "1"]]. Second, it returns a list of ordered binary values. But more importantly, in my opinion, it is closer to the spirit of ocaml.

Adrien Friggeri
Thanks for your reply. I like to get other ideas!Since I'm not familiar with Ocaml, this solution is way more complex to understand. I'll give it a chance in some days ;)
Philipp Andre