Really more of an extended comment, but the whole of this code can be simplified by using a fold
function.
let addormult (n, what) =
let f = if what = "multiply" then (*) else (+)
List.fold f 1 [1..n]
let x = addormult(4, "multiply") // results in x = 24
let y = addormult(4, "add") // results in y = 10
Or even better, define getOp
outside the scope, since it's going to be generally applicable.
let getOp what = if what = "multiply" then (*) else (+)
let addormult (n, what) = List.fold (getOp what) 1 [1..n]
let x = addormult(4, "multiply") // results in x = 24
let y = addormult(4, "add") // results in y = 10
fold
is also tail-recursive, ensuring you don't exceed the stack size limit for large N. In F#, a lot of times when you do recursion, there's already a standard library function that does what you need. Or if not, sometimes it's better to extract a "general" recursion out of your function and then implement your specific thing in terms of that.
Now, note that strings are not the best way to convey intention here. Far better to use a discriminated union to convey your operation:
type Op = Add | Multiply
let getop = function | Multiply -> (*) | Add -> (+)
let addormult (n, what) = List.fold (getop what) 1 [1..n]
let x = addormult(4, Multiply) // results in x = 24
let y = addormult(4, Add) // results in y = 10
That way there's no chance someone could accidentally type "mutliply" and get an unexpected return value.
But really there's no reason to limit to just two operations. It's straightforward to make this work with any operation:
let doOneToN f n = List.fold f 1 [1..n]
let x0 = doOneToN (*) 4 // results in x0 = 24
let y0 = doOneToN (+) 4 // results in y0 = 10
With this, you can easily use partial application to make specialized functions if you want:
let factorial = doOneToN (*) // the `n` argument is "curried"
let triangularSum = doOneToN (+) // the `n` argument is "curried"
let x1 = factorial 4 // results in x1 = 24
let y1 = triangularSum 4 // results in y1 = 10
That's the nice thing about functional programming, is that it's easy to mix and match things.
Of course it's so simple that you might not even care to make a function. It's almost simpler just to call let x = List.fold (*) 1 [1..4]
inline. Functional-first languages tend to be nice and terse that way.