Clement Decker
Clement Decker

Reputation: 137

Obtaining a Unit Where I Should Be Obtaining an Integer

I have been trying to write a recursive function which takes a certain number as an input and outputs the sum of all the numbers that are multiples of 3 and 5 from 1 to the input number (3 + 5 + 9..n).

Here is my code

let rec add_nums n = 
    if n < 1 then 0
    if (n%5 > 0) then 0
    else n + add_nums(n-1)

Upvotes: 2

Views: 92

Answers (2)

Helge Rene Urholm
Helge Rene Urholm

Reputation: 1188

May I boldly suggest using a match?

let rec add_nums n = 
    match n with
    | x when x < 1 -> 0
    | x when x % 5 > 0 -> 0
    | _ -> n + add_nums(n-1)

Adding more conditions then is somewhat "easier" and (can be) more readable...

Using match is also "better" in the regard that it will (possibly) make it easier to see errors in return value.

Upvotes: 6

scrwtp
scrwtp

Reputation: 13577

if's are expressions in F# rather than statements. Since they're expressions, both then and else branches need to have the same return type. What this means in practice is that you cannot have an if without an else branch unless then branch returns a unit (which allows the else branch to be omitted). The compiler sees that else was omitted, and infers that the type of then branch should have been unit.

This fixes it:

let rec add_nums n = 
    if n < 1 
        then 0
        else if (n%5 > 0) 
                 then 0
                 else n + add_nums(n-1)

If you format your if's that way, it will make catching such problems easier.

And arguably you could also put both your predicates in a single if.

Upvotes: 7

Related Questions