Reputation: 713
. 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
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
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
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