I’m a complete newbie in OCaml and trying to create a simple console program.
(*let k = read_int()
let l = read_int()
let m = read_int()
let n = read_int()
let d = read_int()*)
let k = 5
let l = 2
let m = 3
let n = 4
let d = 42
let rec total: int -> int -> int = fun i acc ->
if i > d then
acc
else
if (i mod k) == 0 || (i mod l) == 0 || (i mod m) == 0 || (i mod n) == 0 then
total (i + 1) (acc + 1)
else
total (i + 1) acc;
print_int (total 1 0)
But if I try to compile it, it fails:
PS C:\Users\user> ocamlc -g .\a148.ml
File ".\a148.ml", line 14, characters 2-180:
Warning S: this expression should have type unit.
File ".\a148.ml", line 22, characters 0-21:
Error: This expression has type unit but is here used with type int
So, looks like if expression cannot return value here (why?). I’ve added let binding
let k = 5
let l = 2
let m = 3
let n = 4
let d = 42
let rec total: int -> int -> int = fun i acc ->
let x' = if i > d then
acc
else
if (i mod k) == 0 || (i mod l) == 0 || (i mod m) == 0 || (i mod n) == 0 then
total (i + 1) (acc + 1)
else
total (i + 1) acc;
x'
print_int (total 1 0)
and it works, but raises another error:
File ".\a148.ml", line 23, characters 0-0:
Error: Syntax error
Line 23 is the next to print_int statement and empty, so it seems like compiler wants something else from me, but I don’t know what.
UPD: ok, the working code:
let k = 5 in
let l = 2 in
let m = 3 in
let n = 4 in
let d = 42 in
let rec total i acc =
if i > d then
acc
else
if (i mod k) == 0 || (i mod l) == 0 || (i mod m) == 0 || (i mod n) == 0 then
total (i + 1) (acc + 1)
else
total (i + 1) acc
in let x = total 1 0 in
print_int x;
The problem is the misuse of semicolon (
;).Semicolon intends to be the sequence composition of two expressions.
S1 ; S2means that the compiler expectsS1to beunittype, computesS1andS2in that order and returns the result ofS2.Here you mistakenly use
;, so OCaml expects the secondif...then...elseto returnunitand wants you to provide one more expression. Removing;and adding necessaryin(s) should make the function compile:Regarding your second function, you should replace
;byinto indicate thatx'is used to compute the return value.BTW, your
totalfunction looks weird since you use lambda expression in the function body. Explicit declaration is more readable:I have also changed reference equality
(==)to structural equality(=)though there is no difference among them in integer.