Tlal
Tlal

Reputation: 713

Ocaml: add up all the integers in an int list and output it as an int Option

. Write a function that takes an integer list and return sum of all elements of the list. If the list is empty then return None.

This is my code now:

let rec sum (xs: int list) =
   match xs with
   | [] -> None
   | [x] -> Some x
   | hd::tl -> let m = (hd + (sum tl)) in
                 Some m
;;

The problem is that I can't seem to find a way to add up the last element without getting an error.
This is my error. Error: This expression has type int but an expression was expected of type 'a option.

Upvotes: 0

Views: 2721

Answers (3)

V. Michel
V. Michel

Reputation: 1619

You can define the addition of two int option.

let sum l =
  let (+) a b =
    match (a,b) with
      | (None,x) | (x,None) -> x
      | (Some x,Some y)     -> Some (x+y)
  in
  let convert a = Some a in
  let opt_l=List.map convert l  in
  List.fold_left (+) None opt_l

Test

# sum [];;
- : int option = None
# sum [1;2];;
- : int option = Some 3

Upvotes: 1

Étienne Millon
Étienne Millon

Reputation: 3028

That looks like an assignment so I'll be vague:

The easiest way to do that is probably to first define a function of type int list -> int that returns the "normal" sum (with 0 for the empty case). That function will be recursive and 0 will correspond to the base case.

Then write another function of type int list -> int option that checks whether its argument is empty or not and does the right thing based on that.

Trying to write the recursion directly probably is not a good idea since there are two cases when you will need to handle []: when it's the only element in the list, and when it's at the end of a nonempty list.

Upvotes: 0

Jeffrey Scofield
Jeffrey Scofield

Reputation: 66823

Your recursive call to sum does indeed return an int option. You know this because you're the author of the function, and you coded it up to return that type :-) You can either write a helper function that returns an int, or you can extract the int from the return value of sum, something like this:

let tlsum =
    match sum tl with
    | None -> (* figure this part out *)
    | Some n -> (* figure this part out *)

Upvotes: 1

Related Questions